Failed to save the file to the "xx" directory.

Failed to save the file to the "ll" directory.

Failed to save the file to the "mm" directory.

Failed to save the file to the "wp" directory.

403WebShell
403Webshell
Server IP : 66.29.132.124  /  Your IP : 13.58.224.40
Web Server : LiteSpeed
System : Linux business141.web-hosting.com 4.18.0-553.lve.el8.x86_64 #1 SMP Mon May 27 15:27:34 UTC 2024 x86_64
User : wavevlvu ( 1524)
PHP Version : 7.4.33
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : OFF  |  Pkexec : OFF
Directory :  /opt/cloudlinux/venv/lib64/python3.11/site-packages/clselect/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /opt/cloudlinux/venv/lib64/python3.11/site-packages/clselect/clselectctlnodejsuser.py
# -*- coding: utf-8 -*-

# Copyright © Cloud Linux GmbH & Cloud Linux Software, Inc 2010-2019 All Rights Reserved
#
# Licensed under CLOUD LINUX LICENSE AGREEMENT
# http://cloudlinux.com/docs/LICENSE.TXT

from __future__ import print_function
from __future__ import absolute_import
from __future__ import division

import os
import pwd
import requests
import requests.packages.urllib3.exceptions as urllib_exceptions                #pylint: disable=E0401
import shutil
from requests.exceptions import ConnectionError
from future.utils import iteritems
from past.builtins import basestring

from . import clpassenger
from . import clselectctl
from . import utils
from clcommon.cpapi import userdomains
from clcommon.utils import mod_makedirs
from .clselectexcept import ClSelectExcept
from .clselectnodejs.apps_manager import ApplicationsManager
from .clselectnodejsuser import environments, interpreters
from .baseclselect import APP_STARTED_CONST, APP_STOPPED_CONST
from .clselectprint import clprint

DEFAULT_STARTUP_FILE = 'app.js'
DEFAULT_APP_STATE = APP_STARTED_CONST


def _create_environment(user, directory, version, env_name=None, destroy_first=False):
    prefix = _get_prefix(user, directory)
    if not env_name:
        env_name = version
    environment = environments.Environment(env_name, user, prefix)
    if not environment.exists() or destroy_first:
        try:
            interpreter = interpreters.interpreters(key='version')[version]
        except KeyError:
            raise ClSelectExcept.NoSuchAlternativeVersion(version)
        environment.create(interpreter, destroy_first=destroy_first)
    return environment


def _get_environment(user, directory, app_summary=None):
    prefix = _get_prefix(user, directory)
    if app_summary is None:
        user_summary = clpassenger.summary(user)
        try:
            app_summary = utils.get_using_realpath_keys(user, directory, user_summary)
        except KeyError:
            raise ClSelectExcept.NoSuchApplication(
                'No such application (or application not configured) "%s"' %
                directory)
    binary = app_summary['binary']
    env_name = os.path.basename(os.path.dirname(os.path.dirname(binary)))
    environment = environments.Environment(env_name, user, prefix)
    return environment


def _get_prefix(user, directory):
    _, rel_dir = utils.get_abs_rel(user, directory)
    return os.path.join(environments.DEFAULT_PREFIX, rel_dir)


def _ensure_version_enabled(version, user):
    """
    Check whether particular interpreter version is enabled and raises
    exception if not
    :param user: user to include in exception
    """
    from .clselectnodejs import node_manager
    if not node_manager.NodeManager().is_version_enabled(version):
        raise ClSelectExcept.UnableToSetAlternative(
            user, version, 'version is not enabled')


def _get_existing_nesting_app_for(new_app_directory, user, apps_manager=None):
    """
    Return None if new_app_directory is not nested inside an existing
    user application, and the name of conflicting application otherwise
    """

    if apps_manager is None:
        apps_manager = ApplicationsManager()

    abs_app_path, _ = utils.get_abs_rel(user, new_app_directory)
    full_config = apps_manager.get_user_config_data(user)
    for existing_app in full_config.keys():
        # In case home directory was symlinked after config was written
        existing_app_abs_path, _ = utils.get_abs_rel(user, existing_app)
        if (abs_app_path + os.sep).startswith(existing_app_abs_path + os.sep):
            return existing_app
    return None


def create(user, directory, alias, version=None, doc_root=None, app_mode=None,
           env_vars=None, startup_file=None, domain_name=None, apps_manager=None, passenger_log_file=None):
    """
    Create application
    :param user: unix user name
    :param directory: application path in user's home (app-root)
    :param alias: alias (app-uri)
    :param version: version of interpreter
    :param doc_root: doc_root
    :param app_mode: application mode for nodejs
    :param env_vars: dict with enviroment variables
    :param startup_file: main application file
    :param domain_name: domain name
    :param apps_manager: Application Manager. Class that responsible
           for gathering and writing information about applications
    :param passenger_log_file: Passenger log filename to write to app's .htaccess
    :return: None
    """

    if apps_manager is None:
        apps_manager = ApplicationsManager()

    if version is None:
        raise ClSelectExcept.WrongData('Not passed version as argument')
    _ensure_version_enabled(version, user)

    if startup_file is None:
        startup_file = DEFAULT_STARTUP_FILE
    if env_vars is None:
        env_vars = {}
    if app_mode is None:
        app_mode = 'production'

    conflicting_app = _get_existing_nesting_app_for(directory, user, apps_manager)
    if conflicting_app is not None:
        raise ClSelectExcept.BusyApplicationRoot(conflicting_app)

    alias = clselectctl.get_alias(alias)
    environment = _create_environment(user, directory, version)
    binary = environment.interpreter().binary

    clpassenger.configure(user, directory, alias, apps_manager.INTERPRETER, binary,
                          doc_root=doc_root, startup_file=startup_file,
                          passenger_log_file=passenger_log_file)
    #  webapp was started
    clpassenger.restart(user, directory)
    if not domain_name:
        # if domain name not defined - try to detemine it
        summary_data = clpassenger.summary(user)
        app_summary = utils.get_using_realpath_keys(user, directory, summary_data)
        domain_name = app_summary['domain']
    app_data = {
        u'nodejs_version': version,
        u'domain': domain_name,
        u'app_uri': alias,
        u'app_status': DEFAULT_APP_STATE,
        u'startup_file': startup_file,
        u'app_mode': app_mode,
        u'config_files': [],
        u'env_vars': env_vars,
    }
    if passenger_log_file:
        app_data[u'passenger_log_file'] = passenger_log_file
    apps_manager.add_app_to_config(user, directory, app_data)
    try:
        apps_manager.add_env_vars_for_htaccess(user, directory, env_vars, doc_root)
    except Exception as err:
        clprint.print_diag('text', {'status': 'ERROR', 'message': str(err)})


def _create_symlink_to_node_modules(username, environment_path, app_root):
    """
    Creates symlink to app's node_modules in app_root
    :param username: user name
    :param environment_path: Path to app's virtual environment
    :param app_root: Application root
    :return: None
    """
    # This function logic is duplicated in npm wrapper, but we still need it here too. See commit
    # message of LVEMAN-1335
    message = 'Cloudlinux NodeJS Selector demands to store node modules for application '\
              'in separate folder (virtual environment) pointed by symlink '\
              'called "node_modules". That`s why application should not contain folder/file '\
              'with such name in application root'
    link_name = os.path.join(pwd.getpwnam(username).pw_dir, app_root, 'node_modules')
    if os.path.islink(link_name):
        try:
            os.remove(link_name)
        except OSError:
            raise ClSelectExcept.RemoveSymlinkError(
                'Can`t remove symlink %(link_name)s' %
                {'link_name': link_name}
            )
    elif os.path.exists(link_name):  # link_name not a old symlink, but exists
        raise ClSelectExcept.SymlinkError(message)
    link_to = os.path.join(environment_path, 'lib/node_modules')
    if not os.path.exists(link_to):
        mod_makedirs(link_to, 0o775)
    try:
        os.symlink(link_to, link_name)
    except OSError:
        raise ClSelectExcept.CreateSymlinkError('Error creating symlink. ' + message)


def destroy(user, app_directory, doc_root, apps_manager=None):
    """
    Destroy web app with specified directory for specified user
    :param user: username
    :param app_directory: application directory
    :param doc_root: Document root for selected domain
    :param apps_manager: Application Manager. Class that responsible
           for gathering and writing information about applications
    :return: None
    """

    if apps_manager is None:
        apps_manager = ApplicationsManager()

    # get app state
    app_config = apps_manager.get_app_config(user, app_directory)
    # remove env from htaccess
    try:
        # if domain is already removed we shouldn't do anything
        if doc_root is not None:
            apps_manager.add_env_vars_for_htaccess(user, app_directory, None, doc_root)
    except Exception as err:
        clprint.print_diag('text', {'status': 'ERROR', 'message': str(err)})

    if app_config.get('app_status') == APP_STOPPED_CONST:
        # stopped app
        user_home = pwd.getpwnam(user).pw_dir
        # Remove app's nodenv, e.g. /home/cltest1/nodevenv/test_app
        nodevenv_path = '/'.join([user_home, 'nodevenv', app_directory])
        try:
            # Remove app's nodenv, e.g. /home/cltest1/nodevenv/test_app
            shutil.rmtree(nodevenv_path)
        except OSError:
            pass
        # if domain is already removed we shouldn't do anything
        if doc_root is not None:
            # Remove NodeJS lines from .htaccess
            htaccess_filename = apps_manager.get_htaccess_by_appdir(user, app_directory, doc_root)
            clpassenger.remove_passenger_lines_from_htaccess(htaccess_filename)
        # remove app from node-selector.json file
        apps_manager.remove_app_from_config(user, app_directory)
        # Update application status in passenger
        try:
            clpassenger.restart(user, app_directory)
        except ClSelectExcept.MissingApprootDirectory:
            pass
        return
    # Moved before removing an app from node-selector.json because in case if
    # app_root is absent we still want to remove venv dir of an application.
    # The method didn't anyhing if app_root is absent and skip other commands
    # including removal of a venv dir
    prefix = _get_prefix(user, app_directory)
    abs_dir, _ = utils.get_abs_rel(user, prefix)
    try:
        # Remove app's nodenv, e.g. /home/cltest1/nodevenv/test_app
        shutil.rmtree(abs_dir)
    except OSError:
        pass
    user_summary = clpassenger.summary(user)
    # remove app from node-selector.json file
    app_in_config = apps_manager.remove_app_from_config(user, app_directory)
    try:
        utils.get_using_realpath_keys(user, app_directory, user_summary)
    except KeyError:
        # if app was existed and app's dir is not exists, we skip all further actions
        if app_in_config:
            return None
        else:
            raise ClSelectExcept.WrongData("No such application (or application not configured) \"%s\""
                                           % app_directory)

    # remove app from passenger
    clpassenger.unconfigure(user, app_directory)        # Clear .htaccess
    try:
        clpassenger.restart(user, app_directory)
    except ClSelectExcept.MissingApprootDirectory:
        pass


def start(user, app_directory, doc_root, apps_manager=None):
    """
    Starts web app with specified directory for specified user
    :param user: username
    :param app_directory: application directory
    :param doc_root: Document root for selected domain
    :param apps_manager: Application Manager. Class that responsible
           for gathering and writing information about applications
    :return: None
    """

    if apps_manager is None:
        apps_manager = ApplicationsManager()

    app_config = apps_manager.get_app_config(user, app_directory)
    if app_config is None:
        raise ClSelectExcept.WrongData("No such application (or application not configured) \"%s\""
                                       % app_directory)
    # Do nothing if application already started
    if app_config.get('app_status') == APP_STARTED_CONST:
        return
    # Create .htaccess file for the application
    apps_manager.update_htaccess_file(user, app_directory, doc_root)
    # Save new application status in user's config
    apps_manager.set_app_status(user, app_directory, APP_STARTED_CONST)
    # Update application status in passenger
    clpassenger.restart(user, app_directory)


def restart(user, app_directory, doc_root, apps_manager=None):
    """
    Restarts web app with specified directory for specified user
    :param user: username
    :param app_directory: application directory
    :param doc_root: Document root for selected domain
    :param apps_manager: Application Manager. Class that responsible
           for gathering and writing information about applications
    :return: None
    """

    if apps_manager is None:
        apps_manager = ApplicationsManager()

    app_config = apps_manager.get_app_config(user, app_directory)
    if app_config is None:
        raise ClSelectExcept.WrongData("No such application (or application not configured) \"%s\""
                                       % app_directory)
    # If application was stopped - start it
    if app_config.get('app_status') == APP_STOPPED_CONST:
        start(user, app_directory, doc_root)
    else:
        clpassenger.restart(user, app_directory)


def stop(user, app_directory, doc_root, apps_manager=None):
    """
    Stops web app with specified directory for specified user
    :param user: username
    :param app_directory: application directory
    :param doc_root: Document root for selected domain
    :param apps_manager: Application Manager. Class that responsible
           for gathering and writing information about applications
    :return: None
    """

    if apps_manager is None:
        apps_manager = ApplicationsManager()

    app_config = apps_manager.get_app_config(user, app_directory)
    if app_config is None:
        raise ClSelectExcept.WrongData("No such application (or application not configured) \"%s\""
                                       % app_directory)
    # Do nothing if application is not started
    if app_config.get('app_status') == APP_STOPPED_CONST:
        return
    htaccess_filename = apps_manager.get_htaccess_by_appdir(user, app_directory, doc_root, app_config)
    # Remove NodeJS lines from .htaccess
    clpassenger.remove_passenger_lines_from_htaccess(htaccess_filename)
    # Save new application status in user's config
    apps_manager.set_app_status(user, app_directory, APP_STOPPED_CONST)
    # Update application status in passenger
    clpassenger.restart(user, app_directory)


def check_response_from_webapp(domain, alias, action=None):
    """
    Check response from user's webapp before and after calling action.
    Also compare both responses
    :param domain: domain associated with webapp
    :param alias: URI associated with webapp
    :param action: called action, that make something with webapp: install modules, transit it, etc
    :return: None
    """

    app_is_inaccessible_before = 'Web application is inaccessible by its address "%s". The operation wasn\'t performed.'
    app_is_inaccessible_after = 'The operation was performed, but check availability of application has failed. ' \
                                'Web application is inaccessible by its address "%s" after the operation.'
    app_is_broken = 'The operation was performed, but check availability of application has failed. ' \
                    'Web application responds, but its return code "%s" or ' \
                    'content type before operation "%s" doesn\'t equal to contet type after operation "%s".'

    requests.packages.urllib3.disable_warnings(urllib_exceptions.InsecureRequestWarning)        #pylint: disable=E1101

    if not callable(action):
        raise ClSelectExcept.WrongData('Wrong action for calling in checking webapp')
    webapp_url = 'https://{domain}/{alias}'.format(
        domain=domain,
        alias=alias,
    )
    # for hiding from the module of Apache `mod_security`
    headers = {
        'User-Agent': 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.13) '
                      'Gecko/20101209 CentOS/3.6-2.el5.centos Firefox/3.6.13'
    }
    try:
        request = requests.get(webapp_url, verify=False, headers=headers)
    except ConnectionError:
        # site is not available by https protocol
        webapp_url = webapp_url.replace('https://', 'http://')
        try:
            request = requests.get(webapp_url, verify=False, headers=headers)
        except ConnectionError:
            raise ClSelectExcept.WebAppError(app_is_inaccessible_before % webapp_url)
    before_mime_type = request.headers.get('Content-Type')
    before_status = request.headers.get('Status')
    action()
    try:
        request = requests.get(webapp_url, verify=False, headers=headers)
    except ConnectionError:
        raise ClSelectExcept.WebAppError(app_is_inaccessible_after % webapp_url)
    after_mime_type = request.headers.get('Content-Type')
    after_status = request.headers.get('Status')
    # assume that app is broken if:
    # it's response Content-Type or Status code (if first code wasn't 500) changed
    # if last Status code was 500 (internal error)
    if before_mime_type.lower() != after_mime_type.lower() or \
        (before_status != after_status and before_status is not None and before_status[:3] != '500') \
            or (after_status is not None and after_status[:3] == '500'):
        raise ClSelectExcept.WebAppError(app_is_broken % (after_status, before_mime_type, after_mime_type))


def _get_info_about_webapp(app_summary=None, user=None):
    """
    Get info (alias and domain) about user's web application
    :param app_summary: dict -> summary info about user's web application
    :param user: str -> name of unix user
    :return: tuple -> (alias, domain)
    """

    if app_summary is None:
        raise ClSelectExcept.WrongData('Was passed incorrect summary info about application')
    if user is None:
        raise ClSelectExcept.WrongData('Was passed incorrect name of user')
    alias = app_summary['alias']
    user_domains = userdomains(user)
    found_domains = [
            domain for domain, doc_root in user_domains
            if utils.realpaths_are_equal(user, doc_root, app_summary['docroot'])]
    if len(found_domains) == 0:
        raise ClSelectExcept.WrongData('Can not found suitable domain for application')
    app_domain = found_domains[0]

    return alias, app_domain


def install(user, directory, extension='-', skip_web_check=False, apps_manager=None):
    """
    Install nodejs extension to user's webapp
    :param user: name os unix user
    :param directory: directory with webapp (app-root)
    :param extension: name and version of extension
    :param skip_web_check: skip check web application after change it's properties
    :param apps_manager: Application Manager. Class that responsible
           for gathering and writing information about applications
    :return: None
    """

    if apps_manager is None:
        apps_manager = ApplicationsManager()

    user_config = apps_manager.get_user_config_data(user)
    try:
        app_data = utils.get_using_realpath_keys(user, directory, user_config)
    except KeyError:
        raise ClSelectExcept.WrongData('Record about application {} is absent'.format(directory))
    if app_data['app_status'] != APP_STARTED_CONST:
        skip_web_check = True
    else:
        alias = app_data['app_uri']
        app_domain = app_data['domain']
    nodejs_version = app_data['nodejs_version']
    cwd, _ = utils.get_abs_rel(user, directory)
    environment = _create_environment(user, directory, nodejs_version)

    def action():
        # npm install
        environment.extension_install(extension=extension, cwd=cwd)
        clpassenger.restart(user, directory)

    if not skip_web_check:
        try:
            check_response_from_webapp(
                domain=app_domain,
                alias=alias,
                action=action,
            )
        except ClSelectExcept.WebAppError as err:
            raise ClSelectExcept.WebAppError('An error occured during installation of modules. %s' % err)
    else:
        action()


def summary(user):
    summ = {}
    for directory, data in iteritems(clpassenger.summary(user)):
        if data['interpreter'] != ApplicationsManager.INTERPRETER:
            continue

        environment = _get_environment(user, directory, data).as_deepdict()
        summ[directory] = {
            'domain': data['domain'],
            'alias': data['alias'],
            'environment': environment['name'],
            'interpreter': environment['interpreter'],
        }
        # add only list with additions domains
        if "domains" in data and len(data["domains"]) > 1:
            summ[directory]["domains"] = data["domains"]

    return summ


def validate_env_vars(env_vars):
    if type(env_vars) is not dict:
        raise TypeError
    for item in env_vars:
        if not isinstance(env_vars[item], basestring):
            raise TypeError
    return env_vars

Youez - 2016 - github.com/yon3zu
LinuXploit