diff --git a/api/api.py b/api/api.py index 640c79dc..680350cf 100644 --- a/api/api.py +++ b/api/api.py @@ -46,7 +46,13 @@ def index(): data = { 'help': 'show all available endpoints', 'login': 'get temporarily token. Must be JSON body: login, password and group for which getting token. METHOD: POST', - 'servers': 'show info about all servers. METHOD: GET', + 'user': 'show info about all users inside a group. METHOD: GET', + 'user': 'create a new user inside a group. Must be JSON body: username, email, password, role. METHOD: POST', + 'server': 'show info about all servers. METHOD: GET', + 'server': 'create a new server inside a group. Must be JSON body: hostname, ip, port, virt: enter 0 if is not Virtual IP, group_id, master_id: enter 0 if is not slave, cred_id, description. METHOD: POST', + 'server/ssh': 'show info about all SSH credentials inside a group. METHOD: GET', + 'server/ssh': 'create a new SSH credentials inside a group. Must be JSON body: name, key_enabled, username, password. METHOD: POST', + 'server/ssh/key': 'upload a new SSH key inside a group. Must be JSON body: name, key. Name it is credentials name, in key new lines must be replaced with "\n" METHOD: POST', 'servers/status': 'show status all HAProxyes. METHOD: GET', 'haproxy/': 'show info about the HAProxy by id or hostname or ip. METHOD: GET', 'haproxy//status': 'show HAProxy status by id or hostname or ip. METHOD: GET', @@ -94,14 +100,14 @@ def get_token(): return dict(token=token) -@route('/servers', method=['GET']) +@route('/server', method=['GET']) def get_servers(): if not check_login(): return dict(error=_error_auth) data = {} try: token = request.headers.get('token') - login, group_id = sql.get_username_groupid_from_api_token(token) + login, group_id, role_id = sql.get_username_groupid_from_api_token(token) servers = roxywi_common.get_dick_permit(username=login, group_id=group_id, token=token) for s in servers: @@ -117,12 +123,54 @@ def get_servers(): 'alert': s[8], 'metrics': s[9] } - except Exception: - pass + except Exception as e: + data = {'error': e} return dict(servers=data) +@route('/server', method=['POST']) +def show_users(): + if not check_login(): + return dict(error=_error_auth) + return api_funct.create_server() + + +@route('/user', method=['GET']) +def show_users(): + if not check_login(): + return dict(error=_error_auth) + return api_funct.user_list() + + +@route('/user', method=['POST']) +def create_user(): + if not check_login(): + return dict(error=_error_auth) + return api_funct.create_user() + + +@route('/server/ssh', method=['GET']) +def show_ssh(): + if not check_login(): + return dict(error=_error_auth) + return api_funct.ssh_list() + + +@route('/server/ssh', method=['POST']) +def create_ssh(): + if not check_login(): + return dict(error=_error_auth) + return api_funct.create_ssh() + + +@route('/server/ssh/key', method=['POST']) +def upload_ssh_key(): + if not check_login(): + return dict(error=_error_auth) + return api_funct.upload_ssh_key() + + @route('/servers/status', method=['GET']) def servers_status(): if not check_login(): diff --git a/api/api_funct.py b/api/api_funct.py index 05e27ff0..15c0ac80 100644 --- a/api/api_funct.py +++ b/api/api_funct.py @@ -5,12 +5,14 @@ from bottle import request sys.path.append(os.path.join(sys.path[0], '/var/www/haproxy-wi/app/')) import modules.db.sql as sql +import modules.server.ssh as ssh_mod import modules.server.server as server_mod import modules.config.section as section_mod import modules.config.config as config_mod import modules.config.runtime as runtime_mod import modules.roxy_wi_tools as roxy_wi_tools import modules.roxywi.logs as roxywi_logs +import modules.roxywi.user as roxywi_user import modules.roxywi.common as roxywi_common import modules.service.common as service_common @@ -55,7 +57,8 @@ def get_token(): if login in user.username and password == user.password: import uuid user_token = str(uuid.uuid4()) - sql.write_api_token(user_token, group_id, user.role, user.username) + role_id = sql.get_role_id_by_name(user.role) + sql.write_api_token(user_token, group_id, role_id, user.username) return user_token else: return False @@ -110,7 +113,7 @@ def return_dict_from_out(server_id, out): def check_permit_to_server(server_id, service='haproxy'): servers = sql.select_servers(id_hostname=server_id) token = request.headers.get('token') - login, group_id = sql.get_username_groupid_from_api_token(token) + login, group_id, role_id = sql.get_username_groupid_from_api_token(token) for s in servers: server = roxywi_common.get_dick_permit(username=login, group_id=group_id, ip=s[2], token=token, service=service) @@ -215,7 +218,7 @@ def get_all_statuses(): try: servers = sql.select_servers() token = request.headers.get('token') - login, group_id = sql.get_username_groupid_from_api_token(token) + login, group_id, role_id = sql.get_username_groupid_from_api_token(token) sock_port = sql.get_setting('haproxy_sock_port') for s in servers: @@ -344,7 +347,7 @@ def edit_section(server_id): token = request.headers.get('token') servers = check_permit_to_server(server_id) hap_configs_dir = get_config_var.get_config_var('configs', 'haproxy_save_configs_dir') - login, group_id = sql.get_username_groupid_from_api_token(token) + login, group_id, role_id = sql.get_username_groupid_from_api_token(token) if save == '': save = 'save' @@ -400,7 +403,7 @@ def upload_config(server_id, **kwargs): body = request.body.getvalue().decode('utf-8') save = request.headers.get('action') token = request.headers.get('token') - login, group_id = sql.get_username_groupid_from_api_token(token) + login, group_id, role_id = sql.get_username_groupid_from_api_token(token) nginx = '' apache = '' @@ -471,7 +474,7 @@ def add_to_config(server_id): save = request.headers.get('action') hap_configs_dir = get_config_var.get_config_var('configs', 'haproxy_save_configs_dir') token = request.headers.get('token') - login, group_id = sql.get_username_groupid_from_api_token(token) + login, group_id, role_id = sql.get_username_groupid_from_api_token(token) time_zone = sql.get_setting('time_zone') get_date = roxy_wi_tools.GetDate(time_zone) @@ -683,3 +686,112 @@ def generate_acl(**kwargs): acl += then_value + ' if { ' + acl_if_word + if_value + ' } ' + newline return acl + + +def user_list(): + data = {} + token = request.headers.get('token') + login, group_id, role_id = sql.get_username_groupid_from_api_token(token) + users = sql.select_users(by_group_id=group_id) + for user in users: + data[user.user_id] = { + 'login': user.username, + 'email': user.email, + 'role': user.role, + 'ldap': user.ldap_user, + 'enabled': user.activeuser, + 'last_login_ip': user.last_login_ip, + } + data = {'users': data} + return dict(data) + + +def create_user(): + body = request.body.getvalue().decode('utf-8') + json_loads = json.loads(body) + name = json_loads['name'] + email = json_loads['email'] + password = json_loads['password'] + role = json_loads['role'] + token = request.headers.get('token') + login, group_id, role_id = sql.get_username_groupid_from_api_token(token) + + if roxywi_user.create_user(name, email, password, role, 1, group_id, role_id=role_id, token=token): + data = {'status': 'done'} + return dict(data) + else: + data = {'status': 'something went wrong'} + return dict(data) + + +def ssh_list(): + data = {} + token = request.headers.get('token') + login, group_id, role_id = sql.get_username_groupid_from_api_token(token) + sshs = sql.select_ssh(group=group_id) + for ssh in sshs: + data[ssh.id] = { + 'name': ssh.name, + 'username': ssh.username, + 'key_enabled': ssh.enable, + } + data = {'creds': data} + return dict(data) + + +def create_ssh(): + body = request.body.getvalue().decode('utf-8') + json_loads = json.loads(body) + name = json_loads['name'] + enable = json_loads['key_enabled'] + username = json_loads['username'] + password = json_loads['password'] + token = request.headers.get('token') + login, group_id, role_id = sql.get_username_groupid_from_api_token(token) + if ssh_mod.create_ssh_cread_api(name, enable, group_id, username, password): + data = {'status': 'done'} + return dict(data) + else: + data = {'status': 'error: check all fields'} + return dict(data) + + +def upload_ssh_key(): + body = request.body.getvalue().decode('utf-8') + json_loads = json.loads(body) + name = json_loads['name'] + key = json_loads['key'] + token = request.headers.get('token') + login, group_id, role_id = sql.get_username_groupid_from_api_token(token) + groups = sql.select_groups(id=group_id) + for group in groups: + user_group = group.name + if ssh_mod.upload_ssh_key(name, user_group, key): + data = {'status': 'done'} + return dict(data) + else: + data = {'status': 'error: check all fields'} + return dict(data) + + +def create_server(): + body = request.body.getvalue().decode('utf-8') + json_loads = json.loads(body) + hostname = json_loads['hostname'] + ip = json_loads['ip'] + port = json_loads['port'] + virt = json_loads['virt'] + master_id = json_loads['master_id'] + cred_id = json_loads['cred_id'] + desc = json_loads['description'] + token = request.headers.get('token') + login, group_id, role_id = sql.get_username_groupid_from_api_token(token) + + try: + if server_mod.create_server(hostname, ip, group_id, virt, 1, master_id, cred_id, port, desc, 0, 0, 0, 0, '1', role_id=role_id, token=token): + data = {'status': 'done'} + roxywi_common.logging(ip, f'A new server {hostname} has been created', roxywi=1, keep_history=1, service='server') + return dict(data) + except Exception as e: + data = {'status': f'error: {e}'} + return dict(data) diff --git a/app/create_db.py b/app/create_db.py index 70a53941..15befd45 100644 --- a/app/create_db.py +++ b/app/create_db.py @@ -966,7 +966,7 @@ def update_db_v_6_2_1(): def update_ver(): try: - Version.update(version='6.3.1.0').execute() + Version.update(version='6.3.2.0').execute() except Exception: print('Cannot update version') diff --git a/app/modules/db/sql.py b/app/modules/db/sql.py index 1ea67a69..d52ba0dd 100755 --- a/app/modules/db/sql.py +++ b/app/modules/db/sql.py @@ -391,6 +391,8 @@ def select_users(**kwargs): ).join(UserGroups, on=(User.user_id == UserGroups.user_id)).where( UserGroups.user_group_id == kwargs.get("group") )) + elif kwargs.get('by_group_id'): + query = User.select().where(User.groups == kwargs.get("by_group_id")) else: cur_date = get_date.return_date('regular', timedelta_minutes_minus=15) query = User.select(User, Case(0, [( @@ -400,7 +402,7 @@ def select_users(**kwargs): except Exception as e: out_error(e) else: - return query_res + return query def select_user_groups(user_id, **kwargs): @@ -671,7 +673,7 @@ def get_username_groupid_from_api_token(token): except Exception as e: return str(e) else: - return user_name.user_name, user_name.user_group_id + return user_name.user_name, user_name.user_group_id, user_name.user_role def get_token(uuid): diff --git a/app/modules/roxywi/auth.py b/app/modules/roxywi/auth.py index 512c9adc..915009a5 100644 --- a/app/modules/roxywi/auth.py +++ b/app/modules/roxywi/auth.py @@ -35,14 +35,19 @@ def check_login(user_uuid, token, **kwargs): return False -def is_admin(level=1): - cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE")) - user_id = cookie.get('uuid') - try: - role = sql.get_user_role_by_uuid(user_id.value) - except Exception: - role = 4 - pass +def is_admin(level=1, **kwargs): + if kwargs.get('role_id'): + role = kwargs.get('role_id') + else: + cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE")) + user_id = cookie.get('uuid') + user_id = user_id.value + + try: + role = sql.get_user_role_by_uuid(user_id) + except Exception: + role = 4 + pass try: return True if role <= level else False diff --git a/app/modules/roxywi/user.py b/app/modules/roxywi/user.py index f6df345a..f8eb02e4 100644 --- a/app/modules/roxywi/user.py +++ b/app/modules/roxywi/user.py @@ -11,29 +11,12 @@ import modules.alerting.alerting as alerting form = common.form -def create_user(): - email = form.getvalue('newemail') - password = form.getvalue('newpassword') - role = form.getvalue('newrole') - new_user = form.getvalue('newusername') - page = form.getvalue('page') - activeuser = form.getvalue('activeuser') - group = form.getvalue('newgroupuser') - role_id = sql.get_role_id_by_name(role) +def create_user(new_user: str, email: str, password: str, role: str, activeuser: int, group: int, **kwargs) -> bool: + if roxywi_common.check_user_group(token=kwargs.get('token')): - if roxywi_common.check_user_group(): - if roxywi_auth.is_admin(level=role_id): + if roxywi_auth.is_admin(level=2, role_id=kwargs.get('role_id')): try: sql.add_user(new_user, email, password, role, activeuser, group) - env = Environment(loader=FileSystemLoader('templates/'), autoescape=True) - template = env.get_template('ajax/new_user.html') - - template = template.render(users=sql.select_users(user=new_user), - groups=sql.select_groups(), - page=page, - roles=sql.select_roles(), - adding=1) - print(template) roxywi_common.logging(f'a new user {new_user}', ' has been created ', roxywi=1, login=1) try: message = f"A user has been created for you on Roxy-WI portal!\n\n" \ @@ -47,10 +30,13 @@ def create_user(): except Exception as e: print(f'error: Cannot create a new user: {e}') roxywi_common.logging('error: Cannot create a new user', e, roxywi=1, login=1) + return False else: print('error: dalsdm') roxywi_common.logging(new_user, ' tried to privilege escalation', roxywi=1, login=1) + return False + return True def delete_user(): userdel = form.getvalue('userdel') diff --git a/app/modules/server/server.py b/app/modules/server/server.py index 1c89f238..7e39e99d 100644 --- a/app/modules/server/server.py +++ b/app/modules/server/server.py @@ -3,6 +3,7 @@ import json import modules.db.sql as sql import modules.server.ssh as mod_ssh import modules.common.common as common +import modules.roxywi.auth as roxywi_auth import modules.roxywi.common as roxywi_common form = common.form @@ -408,3 +409,56 @@ def show_firewalld_rules() -> None: template = env.get_template('ajax/firewall_rules.html') template = template.render(input=input_chain2, IN_public_allow=in_public_allow, output=output_chain) print(template) + + +def create_server(hostname, ip, group, typeip, enable, master, cred, port, desc, haproxy, nginx, apache, firewall, scan_server, **kwargs) -> bool: + if not roxywi_auth.is_admin(level=2, role_id=kwargs.get('role_id')): + raise Exception('not enough permission') + + if sql.add_server(hostname, ip, group, typeip, enable, master, cred, port, desc, haproxy, nginx, apache, firewall): + try: + if scan_server == '1': + nginx_config_path = sql.get_setting('nginx_config_path') + haproxy_config_path = sql.get_setting('haproxy_config_path') + haproxy_dir = sql.get_setting('haproxy_dir') + apache_config_path = sql.get_setting('apache_config_path') + keepalived_config_path = sql.get_setting('keepalived_config_path') + + if is_file_exists(ip, nginx_config_path): + sql.update_nginx(ip) + + if is_file_exists(ip, haproxy_config_path): + sql.update_haproxy(ip) + + if is_file_exists(ip, keepalived_config_path): + sql.update_keepalived(ip) + + if is_file_exists(ip, apache_config_path): + sql.update_apache(ip) + + if is_file_exists(ip, haproxy_dir + '/waf/bin/modsecurity'): + sql.insert_waf_metrics_enable(ip, "0") + sql.insert_waf_rules(ip) + + if is_service_active(ip, 'firewalld'): + sql.update_firewall(ip) + + except Exception as e: + roxywi_common.logging(f'Cannot scan a new server {hostname}', str(e), roxywi=1) + raise Exception(f'error: Cannot scan a new server {hostname} {e}') + + try: + sql.insert_new_checker_setting_for_server(ip) + except Exception as e: + roxywi_common.logging(f'Cannot insert Checker settings for {hostname}', str(e), roxywi=1) + raise Exception(f'error: Cannot insert Checker settings for {hostname} {e}') + + try: + get_system_info(ip) + except Exception as e: + roxywi_common.logging(f'Cannot get information from {hostname}', str(e), roxywi=1, login=1) + raise Exception(f'error: Cannot get information from {hostname} {e}') + + return True + else: + return False diff --git a/app/modules/server/ssh.py b/app/modules/server/ssh.py index 2b568641..667ffee5 100644 --- a/app/modules/server/ssh.py +++ b/app/modules/server/ssh.py @@ -69,18 +69,32 @@ def create_ssh_cred() -> None: template = env.get_template('/new_ssh.html') output_from_parsed_template = template.render(groups=sql.select_groups(), sshs=sql.select_ssh(name=name), page=page) print(output_from_parsed_template) - roxywi_common.logging('Roxy-WI server', f'A new SSH credentials {name} has created', roxywi=1, login=1) + roxywi_common.logging('Roxy-WI server', f'New SSH credentials {name} has been created', roxywi=1, login=1) -def upload_ssh_key() -> None: - user_group = roxywi_common.get_user_group() - name = common.checkAjaxInput(form.getvalue('name')) +def create_ssh_cread_api(name: str, enable: str, group: str, username: str, password: str) -> bool: + groups = sql.select_groups(id=group) + for group in groups: + user_group = group.name + name = common.checkAjaxInput(name) + name = f'{name}_{user_group}' + enable = common.checkAjaxInput(enable) + username = common.checkAjaxInput(username) + password = common.checkAjaxInput(password) + if username is None or name is None: + return False + else: + if sql.insert_new_ssh(name, enable, group, username, password): + return True + + +def upload_ssh_key(name: str, user_group: str, key: str) -> bool: try: - key = paramiko.pkey.load_private_key(form.getvalue('ssh_cert')) + key = paramiko.pkey.load_private_key(key) except Exception as e: print(f'error: Cannot save SSH key file: {e}') - return + return False lib_path = get_config.get_config_var('main', 'lib_path') full_dir = f'{lib_path}/keys/' @@ -104,7 +118,7 @@ def upload_ssh_key() -> None: key.write_private_key_file(ssh_keys) except Exception as e: print(f'error: Cannot save SSH key file: {e}') - return + return False else: print(f'success: SSH key has been saved into: {ssh_keys}') @@ -112,8 +126,10 @@ def upload_ssh_key() -> None: os.chmod(ssh_keys, 0o600) except IOError as e: roxywi_common.logging('Roxy-WI server', e.args[0], roxywi=1) + return False roxywi_common.logging("Roxy-WI server", f"A new SSH cert has been uploaded {ssh_keys}", roxywi=1, login=1) + return True def update_ssh_key() -> None: diff --git a/app/modules/server/ssh_connection.py b/app/modules/server/ssh_connection.py index ef4c3827..6ae76223 100644 --- a/app/modules/server/ssh_connection.py +++ b/app/modules/server/ssh_connection.py @@ -35,20 +35,20 @@ class SshConnection: banner_timeout=200 ) except paramiko.AuthenticationException: - raise paramiko.SSHException('error: Authentication failed, please verify your credentials') + raise paramiko.SSHException(f'{self.server_ip} Authentication failed, please verify your credentials') except paramiko.SSHException as sshException: - raise paramiko.SSHException(f'error: Unable to establish SSH connection: {sshException}') + raise paramiko.SSHException(f'{self.server_ip} Unable to establish SSH connection: {sshException}') except paramiko.PasswordRequiredException as e: - raise paramiko.SSHException(f'error: {e}') + raise paramiko.SSHException(f'{self.server_ip} {e}') except paramiko.BadHostKeyException as badHostKeyException: - raise paramiko.SSHException(f'error: Unable to verify server\'s host key: {badHostKeyException}') + raise paramiko.SSHException(f'{self.server_ip} Unable to verify server\'s host key: {badHostKeyException}') except Exception as e: if e == "No such file or directory": - raise paramiko.SSHException(f'error: {e}. Check SSH key') + raise paramiko.SSHException(f'{self.server_ip} {e}. Check SSH key') elif e == "Invalid argument": - raise paramiko.SSHException('error: Check the IP of the server') + raise paramiko.SSHException(f'{self.server_ip} Check the IP of the server') else: - raise paramiko.SSHException(f'error: {e}') + raise paramiko.SSHException(f'{self.server_ip} {e}') return self def __exit__(self, exc_type, exc_val, exc_tb): diff --git a/app/options.py b/app/options.py index 3bb3fcd5..009d6303 100644 --- a/app/options.py +++ b/app/options.py @@ -175,7 +175,7 @@ if form.getvalue("change_pos") is not None: sql.update_server_pos(pos, server_id) if form.getvalue('show_ip') is not None and serv is not None: - commands = ["sudo ip a |grep inet |egrep -v '::1' |awk '{ print $2 }' |awk -F'/' '{ print $1 }'"] + commands = ['sudo hostname -i | tr " " "\n"|grep -v "%"'] server_mod.ssh_command(serv, commands, ip="1") if form.getvalue('showif'): @@ -954,7 +954,24 @@ error_mess = 'error: All fields must be completed' if form.getvalue('newuser') is not None: import modules.roxywi.user as roxywi_user - roxywi_user.create_user() + email = common.checkAjaxInput(form.getvalue('newemail')) + password = common.checkAjaxInput(form.getvalue('newpassword')) + role = common.checkAjaxInput(form.getvalue('newrole')) + new_user = common.checkAjaxInput(form.getvalue('newusername')) + page = common.checkAjaxInput(form.getvalue('page')) + activeuser = common.checkAjaxInput(form.getvalue('activeuser')) + group = common.checkAjaxInput(form.getvalue('newgroupuser')) + + if roxywi_user.create_user(new_user, email, password, role, activeuser, group): + env = Environment(loader=FileSystemLoader('templates/'), autoescape=True) + template = env.get_template('ajax/new_user.html') + + template = template.render(users=sql.select_users(user=new_user), + groups=sql.select_groups(), + page=page, + roles=sql.select_roles(), + adding=1) + print(template) if form.getvalue('userdel') is not None: import modules.roxywi.user as roxywi_user @@ -994,47 +1011,7 @@ if form.getvalue('newserver') is not None: print('error: IP or DNS name is not valid') sys.exit() try: - if sql.add_server(hostname, ip, group, typeip, enable, master, cred, port, desc, haproxy, nginx, apache, firewall): - - try: - if scan_server == '1': - nginx_config_path = sql.get_setting('nginx_config_path') - haproxy_config_path = sql.get_setting('haproxy_config_path') - haproxy_dir = sql.get_setting('haproxy_dir') - apache_config_path = sql.get_setting('apache_config_path') - keepalived_config_path = sql.get_setting('keepalived_config_path') - - if server_mod.is_file_exists(ip, nginx_config_path): - sql.update_nginx(ip) - - if server_mod.is_file_exists(ip, haproxy_config_path): - sql.update_haproxy(ip) - - if server_mod.is_file_exists(ip, keepalived_config_path): - sql.update_keepalived(ip) - - if server_mod.is_file_exists(ip, apache_config_path): - sql.update_apache(ip) - - if server_mod.is_file_exists(ip, haproxy_dir + '/waf/bin/modsecurity'): - sql.insert_waf_metrics_enable(ip, "0") - sql.insert_waf_rules(ip) - - if server_mod.is_service_active(ip, 'firewalld'): - sql.update_firewall(ip) - except Exception as e: - roxywi_common.logging('Cannot scan a new server ' + hostname, str(e), roxywi=1) - - try: - sql.insert_new_checker_setting_for_server(ip) - except Exception as e: - roxywi_common.logging('Cannot insert Checker settings for ' + hostname, str(e), roxywi=1) - - try: - server_mod.get_system_info(ip) - except Exception as e: - roxywi_common.logging('Cannot get information from ' + hostname, str(e), roxywi=1, login=1) - + if server_mod.create_server(hostname, ip, group, typeip, enable, master, cred, port, desc, haproxy, nginx, apache, firewall, scan_server): try: user_subscription = roxywi_common.return_user_status() except Exception as e: @@ -1162,7 +1139,11 @@ if form.getvalue('updatessh'): ssh_mod.update_ssh_key() if form.getvalue('ssh_cert'): - ssh_mod.upload_ssh_key() + user_group = roxywi_common.get_user_group() + name = common.checkAjaxInput(form.getvalue('name')) + key = form.getvalue('ssh_cert') + + ssh_mod.upload_ssh_key(user_group, name, key) if form.getvalue('newtelegram'): import modules.alerting.alerting as alerting diff --git a/app/templates/include/login.html b/app/templates/include/login.html index 3b66b8e9..be59ca37 100644 --- a/app/templates/include/login.html +++ b/app/templates/include/login.html @@ -1,5 +1,5 @@ {% if user %} - + {% else %} {% endif %} diff --git a/inc/css/awesome.css b/inc/css/awesome.css index de0a4d22..d4d9de60 100644 --- a/inc/css/awesome.css +++ b/inc/css/awesome.css @@ -421,3 +421,12 @@ font-family: "Font Awesome 5 Solid"; content: "\f0f3"; } +.user-circle::before { + display: none; + font-family: "Font Awesome 5 Solid"; + content: "\f2bd"; +} +.user-circle > .fa-user-circle { + cursor: pointer; + padding-right: 5px; +} diff --git a/inc/css/style.css b/inc/css/style.css index 602c898d..237eeccc 100644 --- a/inc/css/style.css +++ b/inc/css/style.css @@ -185,6 +185,7 @@ pre { margin-right: 30px; color: #fff !important; font-size: 15px; + cursor: pointer; } .auto-refresh { margin-left: auto;