REDROOM
PHP 8.3.31
Path:
Logout
Edit File
Size: 6.10 KB
Close
/proc/thread-self/root/opt/cloudlinux/venv/lib/python3.11/site-packages/clcommon/public_hooks/bin/post_modify_domain.py
Text
Base64
#!/opt/cloudlinux/venv/bin/python3 -bb # -*- coding: utf-8 -*- # Copyright © Cloud Linux GmbH & Cloud Linux Software, Inc 2010-2018 All Rights Reserved # # Licensed under CLOUD LINUX LICENSE AGREEMENT # http://cloudlinux.com/docs/LICENSE.TXT # """ Domain POST modification hook. This script must be called AFTER different domain-related changes in control panel. See --help and docs for detailed description of actions and parameters. """ import argparse import os import re import sys from clcommon.public_hooks.lib import ModifyDomainHook from clcommon.public_hooks import setup_logger_and_sentry # Use the shared username regex (allows dots) — bugbot finding a39cebf7 from clcommon.public_hooks.lib.helpers import _VALID_NAME_RE as _VALID_USERNAME_RE # Domain-name validator. Unicode-aware: each label may contain letters and # digits in any script (so IDN domains like `реселлер41.com` or `日本.jp` # pass through). Plesk fires `phys_hosting_create` with the Unicode form, # not the Punycode form (CLOS-4470); the prior strict-ASCII regex stalled # `_wait_for_plesk_hooks` on i18n test fixtures because the dispatch to # this script bailed before logging `ended post_create_domain ... <domain>`. # # Structural rules per RFC 1035/5890: # - 1..63 chars per label # - label starts and ends with a letter/digit (no leading/trailing `-`) # - labels joined by literal `.` # Total length bound (1..253) is checked separately by `_validate_domain`. # # Forbidden chars (shell metas, path separators, control chars, whitespace) # are naturally excluded because they're neither word chars nor `-`. _DOMAIN_LABEL = r'[^\W_](?:[\w-]{0,61}[^\W_])?' _VALID_DOMAIN_RE = re.compile(rf'\A{_DOMAIN_LABEL}(?:\.{_DOMAIN_LABEL})*\Z') def _validate_username(value): if not value or len(value) > 32 or not _VALID_USERNAME_RE.fullmatch(value): sys.exit(f'Invalid username: {value!r}') def _validate_domain(value): if not value or len(value) > 253 or not _VALID_DOMAIN_RE.fullmatch(value): sys.exit(f'Invalid domain: {value!r}') def _validate_docroot(value): # NOTE(CLOS-4280): the AI-generated hardening in b525447 also rejected # non-absolute paths, but the cPanel SubDomain::changedocroot post-hook # legitimately forwards `dir` as a path relative to the user's home # (see cpanel_postchangesubdomaindocroot_main). Requiring isabs() here # broke the crontab-migration chain wired up in CLOS-3765 and caused # clsolo.python_tests.test_isolated_domains_hooks::test_crontab_migration_and_cleanup # to fail (Tests-all #7057). Rejecting NUL and any `..` segment is # sufficient: this script never opens the path — it only forwards it # to listeners that resolve docroots against the user's home. if not value or '\0' in value or '..' in value.split(os.sep): sys.exit(f'Invalid docroot path: {value!r}') if __name__ == '__main__': setup_logger_and_sentry() parser = argparse.ArgumentParser(description=__doc__) subparsers = parser.add_subparsers(dest='command') create_domain = subparsers.add_parser( 'create', help="[NOT FOR VENDORS PANELS INTEGRATION] Call when domain record is created.") create_domain.add_argument('--username', '-u', required=True, help='User that owns domain.') create_domain.add_argument('--domain', '-ds', required=True, help='Domain name e.g.: `userdomain.com`') modify_domain = subparsers.add_parser( 'modify', help="Call when domain record is updated (e.g " "all sites that have worked on old domain " "now work on a new one).") modify_domain.add_argument('--username', '-u', required=True, help='User that owns domain.') modify_domain.add_argument('--domain', '-ds', required=True, help='Domain name before rename, e.g.: `userdomain.com`') modify_domain.add_argument('--new-domain', '-dt', help='Domain name after rename, e.g.: `userdomain2.eu`') # TODO: how to make this better?' modify_domain.add_argument( '--include-subdomains', required=False, default=False, action='store_true', help='If set, we will also process all domains ' 'that end with domain name (subdomains). ' 'E.g. when renaming olddomain.com -> newdomain.eu ' 'we will also rename sub.olddomain.com to sub.newdomain.eu') modify_domain.add_argument('--old-docroot', help='Old document root path for the domain.') modify_domain.add_argument('--new-docroot', help='New document root path for the domain.') modify_domain = subparsers.add_parser( 'delete', help="[NOT FOR INTEGRATED CONTROL PANELS] Call when domain record is deleted.") modify_domain.add_argument('--username', '-u', required=True, help='User that owns domain.') modify_domain.add_argument('--domain', '-ds', required=True, help='Domain name before rename, e.g.: `userdomain.com`') args = parser.parse_args() hook = ModifyDomainHook() if args.command == 'create': _validate_username(args.username) _validate_domain(args.domain) hook.post_create_domain( args.username, args.domain) elif args.command == 'modify': _validate_username(args.username) _validate_domain(args.domain) if args.new_domain: _validate_domain(args.new_domain) if args.old_docroot: _validate_docroot(args.old_docroot) if args.new_docroot: _validate_docroot(args.new_docroot) kwargs = {'include_subdomains': args.include_subdomains} if args.old_docroot: kwargs['old_docroot'] = args.old_docroot if args.new_docroot: kwargs['new_docroot'] = args.new_docroot hook.post_modify_domain( args.username, args.domain, args.new_domain, **kwargs) elif args.command == 'delete': _validate_username(args.username) _validate_domain(args.domain) hook.post_delete_domain(args.username, args.domain) else: raise NotImplementedError
Save
Close
Exit & Reset
Text mode: syntax highlighting auto-detects file type.
Directory Contents
Dirs: 1 × Files: 5
Delete Selected
Select All
Select None
Sort:
Name
Size
Modified
Enable drag-to-move
Name
Size
Perms
Modified
Actions
__pycache__
DIR
-
drwxr-xr-x
2026-06-23 06:30:22
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
post_modify_admin.py
1.42 KB
lrwxr-xr-x
2026-06-03 13:38:12
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
post_modify_domain.py
6.10 KB
lrwxr-xr-x
2026-06-03 13:38:12
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
post_modify_package.py
1.65 KB
lrwxr-xr-x
2026-06-03 13:38:12
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
post_modify_user.py
3.56 KB
lrwxr-xr-x
2026-06-03 13:38:12
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
pre_modify_user.py
1.24 KB
lrwxr-xr-x
2026-06-03 13:38:12
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
Zip Selected
If ZipArchive is unavailable, a
.tar
will be created (no compression).