HEX
Server: LiteSpeed
System: Linux ws4.angoweb.net 5.14.0-611.13.1.el9_7.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Dec 11 04:57:59 EST 2025 x86_64
User: tswangoe (2287)
PHP: 8.1.33
Disabled: show_source, system, shell_exec, passthru, exec, phpinfo, popen, proc_open
Upload Files
File: //opt/alt/python37/lib/python3.7/site-packages/xray/adviser/__pycache__/cli_api.cpython-37.pyc
B

�*Ud
��@s�dZddlZddlZddlZddlZddlZddlZddlmZddl	m
Z
mZddlm
Z
mZmZmZddlmZddlmZddlmZmZdd	lmZmZmZmZmZmZmZdd
l m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&ddl'm(Z(ddl)m*Z*d
dl+m,Z,d
dl-m.Z.d
dl/m0Z0d
dl1m2Z2m3Z3m4Z4ddl5m6Z6ddl7m8Z8m9Z9m:Z:m;Z;ddl<m=Z=m>Z>m?Z?ddl@mAZAmBZBmCZCddlDmEZEmFZFmGZGmHZHdZIGdd�de�ZJeGdd�d��ZKGdd�d�ZLdS)zB
This module contains X Ray Smart Advice local utility main class
�N)�contextmanager)�asdict�	dataclass)�Any�Tuple�Optional�List)�Enum)�LicenseApproveStatus)�Schema�SchemaError)�is_feature_visible�is_feature_allowed�is_subscription_pending�get_subscription_upgrade_url�get_license_approve_status�approve_license_agreement�get_license_agreement_text)�docroot�is_panel_feature_supported�get_user_emails_list�panel_login_link�	getCPName�userdomains)�drop_privileges)�Feature�)�advice_mapping)�WPOSModuleApply)�SmartAdviceProgress)�advice_list_schema�detailed_advice_schema�user_sites_info_schema�)�
get_client)�advice_pending_storage�advice_processed_storage�advice_list_cache�advice_reason_max_len)�XRayAPIError�	XRayError�SmartAdvicePluginError)�user_mode_advice_verification�username_verification�get_xray_exec_user)�	timestamp�	safe_move�get_user_php_version�filelock�;c@seZdZdZdZdS)�
AdviceActions�apply�rollbackN)�__name__�
__module__�__qualname__�APPLY�ROLLBACK�r<r<�E/opt/alt/python37/lib/python3.7/site-packages/xray/adviser/cli_api.pyr4<sr4c@s6eZdZUeed<eed<eed<eed<eed<dS)�SmartAdviceOptions�
panel_type�	panel_url�panel_emails�upgrade_url�upgrade_url_cdnN)r7r8r9�str�__annotations__r<r<r<r=r>@s

r>c
@s�eZdZdZdd�Zeedd�dd��Zeed�d	d
��Zee	ed�dd
��Z
e	eed�dd�Zee	ed�dd��Z
e	ed�dd�Ze	ed�dd�Zdd�Zeeed�dd��Zeeed�dd�Zee	eeefd�dd ��Zeddeeedd"�d#d$��Ze	eed%�d&d'�Ze	eeeeefd(�d)d*�Zdeed�d+d,�Z e!ed�d-d.��Z"d/d0�Z#dfd1d2�Z$d3d4�Z%e	ed�d5d6�Z&dge	eeeeeeed8�d9d:�Z'dhee	eeeeeeed;�d<d=�Z(ed�d>d?�Z)e	ed�d@dA�Z*dBdC�Z+e!dDdE��Z,didFdG�Z-djdHdI�Z.edJdK��Z/dLdM�Z0edNdO��Z1edPdQ��Z2dRdS�Z3edTdU��Z4dVdW�Z5dkdXdY�Z6e7eee7edZ�d[d\�Z8eee7ee7ed]�d^d_��Z9d`da�Z:dbdc�Z;dS)l�SmartAdviceUtilz%Main Smart Advice local utility classcCs<t�d�|_xttfD]}|�|�qWtd�}|�|_dS)NZsmart_advice�adviser)�loggingZ	getLogger�loggerr%r&�
create_dirr$�adviser_client)�selfZstorZadviser_client_objectr<r<r=�__init__Ks
zSmartAdviceUtil.__init__N)�dpath�returncCstj�|�st�|�dS)zCreate dir if missingN)�os�path�isdir�mkdir)rNr<r<r=rJTszSmartAdviceUtil.create_dir)rOcKs0dt�d�}|r|�|�t�tt|�����S)z�
        Create JSON response message with result field == success
        and given keyword arguments in other fields
        :return: json packed string
        �success)�resultr/)r/�update�json�dumps�dict�sorted�items)�kwargsZinitialr<r<r=�responseZs
zSmartAdviceUtil.response)�a_idrOcCst�d|��S)z%Per-advice file with results of apply�/)r&)r^r<r<r=�_apply_datafilefszSmartAdviceUtil._apply_datafilecCs�|�|�}tj�|�r�zpy"t|��}t�|�}WdQRXWnHtk
rRd}Yn2tjk
r�t|��}|�	�}WdQRXYnXWdt�
|�X|SdS)z=Retrieve data stored in per-advice file with results of applyN)r`rPrQ�isfile�openrW�load�OSError�JSONDecodeError�read�unlink)rLr^Zdatafile�_f�datar<r<r=�_apply_resultsks


zSmartAdviceUtil._apply_resultscCst�d|��S)zPer-advice pending flagr_)r%)r^r<r<r=�
_pending_flag{szSmartAdviceUtil._pending_flag)�	advice_idrOcCstj�|�|��S)zIs advice in pending state)rPrQ�existsrk)rLrlr<r<r=�is_advice_pending�sz!SmartAdviceUtil.is_advice_pendingcCs|�|�dS)zPer-advice progress storagez	.progress)rk)rLr^r<r<r=�_progress_file�szSmartAdviceUtil._progress_filecCs.yt|�Stk
r(|j�d�dSXdS)Nz#Error while getting user login link�)r�	ExceptionrI�	exception)rL�usernamer<r<r=�_get_user_login_link�s
z$SmartAdviceUtil._get_user_login_link)�advice_typerOcCst|S)z>Get appropriate instance of Apply actions class by advice type)r)rur<r<r=�get_advice_instance�sz#SmartAdviceUtil.get_advice_instance)ri�schemarOc
Csby
|�|�Stk
r\}z4|j�d|�|jdp<|jd}td|����Wdd}~XYnXdS)z&Validate given data using given schemaz#Failed to validate API response: %s���zMalformed API response: N)ZvalidaterrI�error�errorsZautosr))rLrirw�e�msgr<r<r=�	_validate�s
zSmartAdviceUtil._validatecCs,|j|j�|�td�}||�|dd�fS)zu
        Get advice details from API along with an
        appropriate Advice object by obtained advice type
        )rirw�advice�type)r}rK�advice_detailsr!rv)rLrlZ	_responser<r<r=�get_detailed_advice�s
z#SmartAdviceUtil.get_detailed_adviceF)�dstri�as_jsonrOc	Csl|d}t|d��F}|rJyt�||�WqTtk
rF|�|�YqTXn
|�|�WdQRXt||�dS)z8Dump data inside given dst using .bkp file and then movez.bkp�wN)rbrW�dump�	TypeError�writer0)r�rir�Z_tmp_dstrhr<r<r=�dump_to_file�szSmartAdviceUtil.dump_to_file)rl�currentrOcs ttd����fdd��}|�S)a
        Smart Advice apply own progress,
        based on current and previous results of 'clwpos get-progress'.
        Returns the maximum progress values among current and previous.
        Previous (latest) is stored inside a pending file-flag.
        )rOc
3s��j�d������}y(t|��}tft�|��}WdQRXWn@ttjfk
r�}z�j�dt	|��t�}Wdd}~XYnX�j�d|��|kr��n|V��
��rֈ|krֈj�d���j|t��dd�dS)z}
            Get progress stored in file and return the maximum one among
            current and stored results
            zCurrent progress value: %sNz%Error during reading stored value: %szStored progress value: %szUpdating stored progress: %sT)r�)
rI�debugrorbrrWrcrdrerDrnr�r)Zprogress_dstZprevZprev_stagesr{)rlr�rLr<r=�resolve_progress�s


z2SmartAdviceUtil.progress.<locals>.resolve_progress)rr)rLrlr�r�r<)rlr�rLr=�progress�szSmartAdviceUtil.progress)�_id�
advice_obj�advice_datarOc	CsX|�|�r:d}|�||�|dd���
}|}WdQRXn|dd}t�}|t|�fS)z�
        Resolve if advice is in pending status.
        Progress is retrieved for pending advice only.
        Dummy result (0, 0) is returned for other advice states.
        �pending�metadatarsNr~�status)rnr�Zget_progressrr)rLr�r�r�r��p�stagesr<r<r=�get_current_status�s

z"SmartAdviceUtil.get_current_statuscCs`|j|j��td�}|j||d�}y|j|d�Wn tk
rR|j�d�YnX|j	|d�S)z9Load validated advice list and update it before returning)rirw)�extended)�current_adviceszDUnable to sync cl-smart-advice plugin during getting list of advices)ri)
r}rK�advice_listr �prepare_advices_response�sync_advices_wordpress_pluginrqrIrrr])rLr��api_responseZresponse_advice_listr<r<r=r��szSmartAdviceUtil.advice_listc	Cs�|j|j�|�td�}i}xP|D]H}|d}||kr<g||<||�|dt|d�|�|d�d��q Wdd�|��D�}|j|d	�S)
N)rirw�domain�websiteZurls�advices)r�Zurls_scannedr�cSsg|]\}}||d��qS))r��websitesr<)�.0r�r�r<r<r=�
<listcomp>	sz5SmartAdviceUtil.get_site_statuses.<locals>.<listcomp>)ri)	r}rKZ	site_infor"�append�lenr�r[r])rLrsr�Zsite_statuses_datar�r�rUr<r<r=�get_site_statuses�s

z!SmartAdviceUtil.get_site_statusescCs2yt�|�dStk
r,t�d�dSXdS)NTzGUser %s does not exist anymore on this server, skipping advices for himF)�pwd�getpwnam�KeyErrorrH�info)rLrsr<r<r=�_does_user_exist_on_servers

z*SmartAdviceUtil._does_user_exist_on_serverc
Cs4|��}g}�x |D�]}|�|dd�s.q|d}|d}|�|�}	|	j|d<|rj|d}
ddd�}n|�|d	|	|�\}
}|r�|	j|d
<|
|d<|	j|d<|	j|d<t|	j|dd�j	|d
<|d�r|�
|	j|dd�}t|t|	j|dd�d�|d<|�
|�t|	j|dd�r|�|�qW|S)Nr�rsr~r�descriptionr�r)Ztotal_stagesZcompleted_stages�id�detailed_descriptionZ
is_premium�module_nameZlicense_status)r�rB�subscription)�copyr�rv�short_descriptionr�r�Zis_premium_featurer�r�name�_get_subscription_statusrYrrVr
r�)
rLZfrom_api�status_from_microservicer�r�Zvisible_advices�item�
advice_itselfru�advice_instancer�r��subscription_statusr<r<r=r�sB







z(SmartAdviceUtil.prepare_advices_responsecCs$d}t||�rd}t||�r d}|S)zQ
        Determines current subscription status based on feature status.
        ZnoZactiver�)rr)rLr�rsr�r<r<r=r�Bs

z(SmartAdviceUtil._get_subscription_statuscCs@|�|�\}}|d}|j|d<|j|d<|j|d<|j|d�S)z<Load validated advice details and update it before returningr~r�r�Z
fix_action)ri)r�r�r�Zapply_button_textr])rLrlr�r�r�r<r<r=r�Ms


zSmartAdviceUtil.advice_details�
ACCELERATE_WP)rl�
ignore_errors�
async_mode�source�reason�accept_termsrOc		CsDt|�|�d���|r.t��}|r.|�|�S|�|||||||�S)Nr�)rbrk�closerP�fork�manage_advice_status�_exec_advice_managing)	rL�actionrlr�r�r�r�r�Zchildr<r<r=�
manage_adviceYs
zSmartAdviceUtil.manage_advice)r�rlr�r�r�r�r�rOcCs��z�|�|�\}}	|tjjkr�|r6t|	j|dd�t|	j|dd�tjkr`t	�
ddd��S|	jf|dd|i��\}
}|
r�|j�
d�|jj|d|d	�y*|�|dd|dd
|dd�Wn tk
r�|j�d�YnXn�|tjjk�r�|	jf|d�\}
}|
�r�|j�
d
�|�rD|jj|d||dt�d�n|jj|d|d	�y*|�|dd|dd
|dd�Wn"tk
�r�|j�d�YnXntd|����Wdt�|�|��X|�r�|�|�|�|�n|SdS)z:Execute managing advice with passed action: apply/rollbackr�rsZLICENCE_TERMS_APPROVE_REQUIREDz�License approve required to use this feature. Open AccelerateWP plugin in your control panel, apply advice and accept terms and conditions to proceed with installation.)rU�textr�zApplied successfully�applied)rlr�r�r�r�z:Error while syncing cl-smart-advice plugin on advice applyzRollback successfullyZreviewN)rlr�r�r�z=Error while syncing cl-smart-advice plugin on advice rollbackz/Unsupported action with advice, passed action: )r�r4r:�valuerr�rr
ZNOT_APPROVEDrWrXr5rIr�rKZ
update_advice�_sync_advicerqrrr;r6r(�
ValueErrorrPrgrkr�r`)rLr�rlr�r�r�r�r�r�r�Z
action_result�outputr<r<r=r�hsb


z%SmartAdviceUtil._exec_advice_managingcCshy|j|j��td�}Wn$tk
r<t�ddgd�}Yn Xtt|�tdd�|D��d�}|j|d�S)	z#Return advice counters for a server)rirw�totalr�NcSs g|]}|dddkr|�qS)r~r�r�r<)r�r~r<r<r=r��sz3SmartAdviceUtil.advice_counters.<locals>.<listcomp>)r�r�)ri)	r}rKr�r r*rY�fromkeysr�r])rLr�rUr<r<r=�advice_counters�szSmartAdviceUtil.advice_countersc	Cs�|�|�\}}|�|||�\}}|�|j|dd�}|dkr�|�|�}|�|�}tj�|�rht�	|�|r�|j
f|t|d�t|j|dd�d�|d|i��S|j
f|t|d�t|j|dd�d�|��S)zS
        Return current status and progress of managing particular advice.
        r�rsr�)�object_cache)r�r�rBri)
r�r�r�r�rjrorPrQrargr]rYr)	rLrlr�r�r�r�r�rUZ	_progressr<r<r=r��s8




z$SmartAdviceUtil.manage_advice_statusc
Cs�|j|j��td�}|�|�}y |�||||j|ddd��Wn&tk
rd|j�	dt
|��dSX|��}|�t�|�t�|��}||kr�i||<||||<|�
|�dS)N)rirwT)r�r�z/Smart Advice plugin sync failed for website: %s)r}rKr�r �!group_alive_advice_ids_by_website�_run_smart_advice_scriptr�rqrIrrrD�_read_advices_cache�advice_cache_separator�_update_advices_cache)rLrsr�r�r��current_advices_by_site�cached_advices_by_site�keyr<r<r=r��s 

zSmartAdviceUtil._sync_advicecCsvyt|�dd}t||�}Wn$tk
rB|j�d�d}YnX|jfttt�|�	|�|t
d|�t
d|�d���S)a'
        gets options:
        "panel_type": "cpanel",
        "panel_url": "https:/cpanel-foo.com/", # or https://plesk-bar.com/
        "panel_emails": "root@hosting.com,manager@hostring.com,foo@bar.com",
        "upgrade_url": "https://...",
        "upgrade_url_cdn": "https://...",
        rzUnable to get user emailsrpr�Zcdn)r?r@rArBrC)rrrqrIrrr]rr>rrtr)rLrsr��emailr<r<r=�get_options�s

zSmartAdviceUtil.get_optionscCsj|s|j|j��td�}|�|�}|s2|jdd�S|��}|j|||j|dd�d�}|�	|�|jdd�S)N)rirwzNo advices found on the server)riT)r�)�current_advices_jsonzPlugin installed)
r}rKr�r r�r]r��_sync_sa_pluginr�r�)rLr�r�r�Z
updated_cacher<r<r=r�s

z-SmartAdviceUtil.sync_advices_wordpress_pluginc
	s�d}i}x�|��D]�\}}|�t�\}�}	|�||�|��sF|||<q|r\�fdd�|D�}y|��|	||�Wn(tk
r�|j�dt	|	��wYnX|||<qW|S)Ncs&g|]}|�di��d��kr|�qS)r�rs)�get)r�r~)rsr<r=r�2sz3SmartAdviceUtil._sync_sa_plugin.<locals>.<listcomp>z/Smart advice plugin sync failed for website: %s)
r[�splitr��_should_sync_websiter�r�rqrIrrrD)
rLr�Zcached_advicesr�Zfiltered_advices_by_userZupdated_advicesr�Zid_status_hashr�r�r<)rsr=r�'s zSmartAdviceUtil._sync_sa_plugincCsZtt�d�d��@}t|��,ttd��}tj||dd�WdQRXWdQRXWdQRXdS)Nz.lockza+r�r#)Zindent)rbr'r2rWr�)Znew_cached_advicesZlock_fd�fr<r<r=r�>s
z%SmartAdviceUtil._update_advices_cachec	Cs\i}tj�t�rXy"tt��}t�|�}WdQRXWn$tk
rV|j�	d�i}YnX|S)Nz!Unable to read advices cache json)
rPrQrmr'rbrWrcrqrIrr)rLr�r�r<r<r=r�Es

z#SmartAdviceUtil._read_advices_cachecCs||kS)Nr<)Zcurrent_hashZcached_hashr<r<r=r�Psz$SmartAdviceUtil._should_sync_websitecCsBt��}x0|D](\}}|�t|����|�|���qW|��S)N)�hashlibZmd5rVrD�encodeZ	hexdigest)�id_status_pairs�hrlr�r<r<r=�	make_hashTs
zSmartAdviceUtil.make_hashcs�i}xj|D]b}|d}|d}|d�t�|d�t�|d��}||krRg||<||�|d|df�q
W�fdd	�|��D�S)
Nr�r~r�rsr�r�r�c	s,i|]$\}}��tt|dd�d���|�qS)cSs|dS)Nrr<)r�r<r<r=�<lambda>h�zNSmartAdviceUtil.group_alive_advice_ids_by_website.<locals>.<dictcomp>.<lambda>)r�)r��tuplerZ)r�r�r�)rLr<r=�
<dictcomp>gszESmartAdviceUtil.group_alive_advice_ids_by_website.<locals>.<dictcomp>)r�r�r[)rLr�r�r~r�r�r�r<)rLr=r�\s
$
z1SmartAdviceUtil.group_alive_advice_ids_by_websitec	Cs$t|d��}|�|�WdQRXdS)z"
        For easy mocking
        r�N)rbr�)rQZcontentr�r<r<r=�_save_custom_phplsz SmartAdviceUtil._save_custom_phpc
	Cs0t�|�j�d�}d}tj�||�}d}d}tj�|�r<dStjd|�d�dddd�}|j	�
dt|j��|jr�||jkr�|j�
��d	|��}n|js�||jkr�d
|��}|�r,|j	�
d||�t|��,tj�|�s�tj|dd
�|�||�WdQRXtjdddd|d|gddd�}	|j	�
dt|	j��dS)Nz/.clwposz.php-iniz/opt/alt/php-xray/z-/usr/sbin/plesk bin site --show-php-settings z | /usr/bin/grep open_basedirT)r��capture_output�shellz!Current open_basedir settings: %s�:zopen_basedir = z/Updated open_basedir setting: %s for domain: %si�)�modez/usr/sbin/plesk�binZsitez--update-php-settingsz	-settings)r�r�z Plesk settings update result: %s)r�r��pw_dirrPrQ�joinrm�
subprocess�runrIr�rD�stdout�striprrRrSr�)
rLrsr�Z
clwpos_dirZ
custom_phpZcustom_php_fullZsa_lineZupdated_settingZopen_basedir_settingrUr<r<r=�_prepare_php_for_pleskts0


z&SmartAdviceUtil._prepare_php_for_pleskc	Cs�|dkr|jgd�}n|j|d�}|�||||�}|�||�}tj|ddd�}|jdkr�|j�dt|j�t|j	�t|j
��td��dS)N)riT)r�r�rzESmart advice plugin failed with exit code: %s, stdout: %s, stderr: %sz'Smart Advice plugin installation failed)r]�!_prepare_smart_advice_script_args�_get_smart_advice_script_cmdr�r��
returncoderIryrDr��stderrr+)	rLrsr�r��advices_jsonZjson_string�attrs�commandrUr<r<r=r��s
z(SmartAdviceUtil._run_smart_advice_script)r�r�rOcCsBd}d|��}|�|�}t�}|�d|��}	|j�d|	�yt||�}
Wn$tk
rl|j�d�d}
YnXt|�d|}t|�}xH|D]}
|
�	d�|kr�|
�	d	�}Pq�W|j�
d
|t|��td|����|s�|j�
d|�td
|����|dk�r.y|�
||�Wn"tk
�r,|j�d�YnX|||||
|	g}|S)Nzrun.shz*/opt/alt/php-xray/php/smart-advice-plugin/�|zPANEL LOGIN LINK %szUnable to get user emailsrprZvhostZ
php_binaryz*Php data for domain %s was not found in %sz%Unable to get php version for domain z)Php version for user: %s was not obtainedz)Php binary was not identified for domain ZPleskz-Setting up php for Plesk for SA plugin failed)rtrrIr�rrqrrrr1r�ryrDr+r�)rLrsr�r�r�Zscript_nameZscript_pathZuser_login_linkZpanelZpanel_user_login_linkr�Zfull_website_pathZphp_infoZphp_dataZphp_binary_path�resr<r<r=r��sF





z1SmartAdviceUtil._prepare_smart_advice_script_args)rsr�rOcCsXttj�r d|dg}|�|�n4d|dd|d<dd�|�}dd|d	dd
|g}|S)Nz/sbin/cagefs_enter_userz	/bin/bash�'�z
/bin/bash � Zsudoz-uz-sz-c)rrZCAGEFS�extendr�)rsr�r�Zcommand_strr<r<r=r��s

z,SmartAdviceUtil._get_smart_advice_script_cmdcCs,t�}|std��t�dt�t||�d��S)z;
        Method with handles work with agreements.
        z)This command can only be executed as userrT)rUr/r�)r.r+rWrXr/r)rL�feature�user_contextr<r<r=�get_agreement_text�sz"SmartAdviceUtil.get_agreement_textc
Cs�t�}|std��|�|�\}}tjddt|�dddt|�d|jg	ddd	�}|jd
kr�|j�	dt|j�t|j
�t|j��td|j��d
S)z�
        Proxy method to AWP which creates subscription
        listening for the status of module and automatic advice appy.
        z)This command can only be executed as userzcloudlinux-awp-userz--userr�z--listenz--advice-idz	--featureT)r�r�rzESmart advice plugin failed with exit code: %s, stdout: %s, stderr: %sz"cloudlinux-awp-user call failed %sN)r.r+r�r�r�rDr�r�rIryr�r�)rLrlr�_r�rUr<r<r=�create_subscription�s$

z#SmartAdviceUtil.create_subscription)F)F)FF)FFr�NF)FFr�NF)N)N)N)<r7r8r9�__doc__rM�staticmethodrDrJr]�intr`rrjrk�boolrnrortrrvrrr}r,rrY�objectr�r�rr�r�r�r-r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�rr�r�rrr<r<r<r=rFHsp		

%
. 
"F*


/
rF)MrrWrHrPr�r�r�Z
contextlibrZdataclassesrrZtypingrrrrZenumr	Zclwpos.user.configr
rwrrZclwpos.papir
rrrrrrZclcommon.cpapirrrrrrZclcommon.clpwdrZclcommon.constrZadvice_typesrZadvice_types.wpos_baserr�rZschemasr r!r"Z	apiclientr$Zinternal.constantsr%r&r'r(Zinternal.exceptionsr)r*r+Zinternal.user_plugin_utilsr,r-r.Zinternal.utilsr/r0r1r2r�r4r>rFr<r<r<r=�<module>
s:$