h &dZddlZddlZddlmZddlmZddlmZm Z ddl m Z ej e ZedZded eefd Zd ejd eefd Zd eefd Zd eefdZdeed dfdZded eefdZdeded dfdZd eefdZdeded dfdZd eefdZded efdZ dS)u  This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program.  If not, see . Copyright © 2019 Cloud Linux Software Inc. This software is also available under ImunifyAV commercial license, see N)Path)SqliteDatabase)WPSite WordpressSite) PLUGIN_SLUGzD/var/lib/cloudlinux-app-version-detector/components_versions.sqlite3pathreturnc<ts;tdt tt St td|d}d|DS)z Get a list of WordPress sites that match the given path. Args: path: The path to search for WordPress sites. Returns: A list of WPSite objects that match the path. -App detector database '%s' couldn't be found.ak WITH latest_reports AS ( SELECT id, uid, domain FROM report WHERE id IN ( SELECT MAX(id) FROM report WHERE domain IS NOT NULL AND domain != '' GROUP BY dir ) ) SELECT wp.real_path, lr.domain, lr.uid FROM apps AS wp INNER JOIN latest_reports AS lr ON wp.report_id = lr.id WHERE wp.title = 'wp_core' AND wp.parent_id IS NULL AND wp.real_path LIKE 'z %' c pg|]3}t|d|dt|d4Sr)docrootdomainuidrint.0rows S/opt/imunify360/venv/lib/python3.11/site-packages/imav/wordpress/site_repository.py z%get_sites_by_path..LI     s1vc!f#c!f++>>>   ) COMPONENTS_DB_PATHexistsloggererrorstrlistr execute_sqlfetchall)rcursors rget_sites_by_pathr%%s  $ $ & & ; " # #   vv . / / ; ; $%)%   F,  ??$$   r user_infoctr|;tdt tt S|(tdt St td|jd}d| DS)aq Get a set of paths to WordPress sites belonging to a particular user. Paths are sorted by their length to make sure that the main site is the last one in the list. The data is pulled from the app-version-detector database. Args: user_info: The user info with ID to get sites for. Returns: A list of paths to WordPress sites. Nr z'No user info provided for getting sitesz WITH latest_reports AS ( SELECT MAX(id) as id FROM report WHERE uid = a] GROUP BY dir ) SELECT wp.real_path FROM apps AS wp INNER JOIN latest_reports AS lr ON wp.report_id = lr.id WHERE wp.title = 'wp_core' AND wp.parent_id IS NULL GROUP BY wp.real_path ORDER BY length(wp.real_path) DESC cg|] }|d S)rrs rrz&get_sites_for_user..|s 0 0 0sCF 0 0 0r) rrrrr r!rr"pw_uidr#)r&r$s rget_sites_for_userr+Rs  $ $ & &)*; ; " # #   vv  5   vv . / / ; ; '-    F$ 1 0foo// 0 0 00rcbts;tdt tt St tdtj ddd}d| DS)z Get a set of wp sites where imunify-security plugin is not installed. The data is pulled from the app-version-detector database. Returns: A set of WPSite objects where the plugin is not installed. r a WITH latest_reports AS ( SELECT id, uid, domain FROM report WHERE id IN ( SELECT MAX(id) FROM report WHERE domain IS NOT NULL AND domain != '' GROUP BY dir ) ) SELECT wp.real_path, lr.domain, lr.uid FROM apps AS wp INNER JOIN latest_reports AS lr ON wp.report_id = lr.id WHERE wp.title = 'wp_core' AND wp.parent_id IS NULL AND NOT EXISTS ( SELECT 1 FROM apps AS plugin WHERE plugin.parent_id = wp.id AND plugin.title = 'wp_plugin_-_z' ) c ph|]3}t|d|dt|d4Sr rrs r z+get_sites_without_plugin..rr) rrrrr setrr"rreplacer#)r$s rget_sites_without_pluginr3s  $ $ & & ; " # #   uu . / / ; ; ,0;/B3/L/L-   F6  ??$$   rcbt}dtjD}||z S)a Get a set of WordPress sites where we need to install the plugin. This is determined by finding sites that don't have the plugin installed and are not already tracked in our database. Returns: A set of WPSite objects where the plugin needs to be installed. c6h|]}tj|Sr)rfrom_wordpress_siterrs rr0z'get_sites_to_install..s0*+"1%%r)r3rselect)sites_without_pluginexisting_sitess rget_sites_to_installr=sD455/.sH  +<x<'+    r)r insert_manyexecute)r>s rinsert_installed_sitesrGsP     giiiiirlatest_versionc|stdgSdtjtjtj|kDS)a Get a list of WordPress sites that have outdated plugin versions. Args: latest_version: The latest available plugin version to compare against. Returns: A list of WPSite objects that have versions older than latest_version. z8Cannot get outdated sites without a valid latest versionc6g|]}tj|Sr)r6r8s rrz&get_outdated_sites..s3     "1%%   r)rrrr:whererBis_nullrA)rHs rget_outdated_sitesrMs  F      %''--  - 5 5 7 7  !^ 3     rrD timestampctd||tj|tj|jkdS)z Mark a WordPress site as manually deleted in the database. Args: site: The WPSite object to mark as deleted timestamp: The timestamp when the site was deleted z:Mark site %s as manually deleted at %s (WP-Plugin removed))rBN)rinforupdaterKrrF)rDrNs rmark_site_as_manually_deletedrRs\ KKD  ;;; }$ 4 5 5 rct}dtjtjD}||zS)a  Get a set of WordPress sites that should be marked as manually deleted. These are sites that are in our database but no longer have the plugin installed. Returns: set[WPSite]: A set of WordPress sites that should be marked as manually deleted c6h|]}tj|Sr)r6r8s rr0z8get_sites_to_mark_as_manually_deleted..s3  "1%%r)r3rr:rKrBrL)r; sites_from_dbs r%get_sites_to_mark_as_manually_deletedrVsf455%''--  - 5 5 7 7  M - //rrActj|tj|jkdS)z Update the version of a WordPress site in the database. Args: site: The WPSite object to update version: The new version to set )rAN)rrQrKrrF)rDrAs rupdate_site_versionrXsA)))//- giiiiircdtjtjdDS)z Get a list of WordPress sites that haven't been marked as manually deleted. Returns: A list of WPSite objects representing non-deleted sites. c6g|]}tj|Sr)r6rCs rrz*get_sites_to_uninstall..1s3     "4((   rT)rr:rKrBrLr)rrget_sites_to_uninstallr[*sP  !(**00  - 5 5d ; ;     rctjtj|jkS)z Delete a WordPress site from the database. Args: site: The WPSite object to delete Returns: The number of rows affected by the delete operation )rdeleterKrrF)rDs r delete_siter^9s5  }$ 4 5 5 r)!__doc__loggingpwdpathlibrpeeweerimav.model.wordpressrrimav.wordpressr getLogger__name__rrr r!r% struct_passwdr+r1r3r=rGrMfloatrRrVrXr[rr^r)rrrjs0* !!!!!!66666666&&&&&&  8 $ $TJ *C*DL****Z*1#"3*1S *1*1*1*1Z.#f+....b 1c&k 1 1 1 1 #f+$2stF|25T(0s6{0000. f s t     V    fr