########################################################################## # # pgAdmin 4 - PostgreSQL Tools # # Copyright (C) 2013 - 2024, The pgAdmin Development Team # This software is released under the PostgreSQL Licence # ########################################################################## """A blueprint module implementing the about box.""" from flask import Response, render_template, request from flask_babel import gettext from flask_security import current_user from pgadmin.user_login_check import pga_login_required from pgadmin.utils import PgAdminModule from pgadmin.utils.menu import MenuItem from pgadmin.utils.constants import MIMETYPE_APP_JS from pgadmin.utils.ajax import make_json_response import config from pgadmin.model import User from user_agents import parse import platform import re MODULE_NAME = 'about' class AboutModule(PgAdminModule): def get_own_menuitems(self): appname = config.APP_NAME return { 'help_items': [ MenuItem( name='mnu_about', priority=999, module="pgAdmin.About", callback='about_show', icon='fa fa-info-circle', label=gettext('About %(appname)s', appname=appname) ) ] } def get_exposed_url_endpoints(self): return ['about.index'] blueprint = AboutModule(MODULE_NAME, __name__, static_url_path='') ########################################################################## # A test page ########################################################################## @blueprint.route("/", endpoint='index') @pga_login_required def index(): """Render the about box.""" info = {} # Get OS , NW.js, Browser details browser, os_details, electron_version = detect_browser(request) admin = is_admin(current_user.email) if electron_version: info['electron'] = electron_version if config.SERVER_MODE: info['app_mode'] = gettext('Server') else: info['app_mode'] = gettext('Desktop') info['commit_hash'] = getattr(config, 'COMMIT_HASH', None) info['browser_details'] = browser info['version'] = config.APP_VERSION info['admin'] = admin info['current_user'] = current_user.email if admin: settings = "" info['os_details'] = os_details info['log_file'] = config.LOG_FILE # If external datbase is used do not display SQLITE_PATH if not config.CONFIG_DATABASE_URI: info['config_db'] = config.SQLITE_PATH for setting in dir(config): if not setting.startswith('_') and setting.isupper() and \ setting not in ['CSRF_SESSION_KEY', 'SECRET_KEY', 'SECURITY_PASSWORD_SALT', 'SECURITY_PASSWORD_HASH', 'ALLOWED_HOSTS', 'MAIL_PASSWORD', 'LDAP_BIND_PASSWORD', 'SECURITY_PASSWORD_HASH']: if isinstance(getattr(config, setting), str): settings = \ settings + '{} = "{}"\n'.format( setting, getattr(config, setting)) else: settings = \ settings + '{} = {}\n'.format( setting, getattr(config, setting)) info['settings'] = settings return make_json_response( data=info, status=200 ) def is_admin(load_user): user = User.query.filter_by(email=load_user).first() return user.has_role("Administrator") def detect_browser(request): """This function returns the browser and os details""" electron_version = None agent = request.environ.get('HTTP_USER_AGENT') try: # available only for python 3.10 and above os_release = platform.freedesktop_os_release() os_details = os_release.get('PRETTY_NAME', '') if os_details: os_details += ', ' except Exception as _: os_details = '' os_details += parse(platform.platform()).ua_string if 'Electron' in agent: electron_version = re.findall('Electron/([\\d.]+\\d+)', agent)[0] browser = re.findall( '(opera|chrome|safari|firefox|msie|trident(?=/))/?\\s*([\\d.]+\\d+)', agent, re.IGNORECASE) if not browser: browser = agent.split('/')[0] else: browser = " ".join(browser[0]) return browser, os_details, electron_version