Files
actions/php-tests/CustomValidator.py
Ismo Vuorinen 96c305c557 refactor: centralize validation logic with validate_with helper (#412)
* chore: sonarcloud fixes

* chore: coderabbit cr fixes
2025-12-23 13:29:37 +02:00

75 lines
2.8 KiB
Python
Executable File

#!/usr/bin/env python3
"""Custom validator for php-tests action."""
from __future__ import annotations
from pathlib import Path
import sys
# Add validate-inputs directory to path to import validators
validate_inputs_path = Path(__file__).parent.parent / "validate-inputs"
sys.path.insert(0, str(validate_inputs_path))
from validators.base import BaseValidator
from validators.network import NetworkValidator
from validators.security import SecurityValidator
from validators.token import TokenValidator
class CustomValidator(BaseValidator):
"""Custom validator for php-tests action."""
def __init__(self, action_type: str = "php-tests") -> None:
"""Initialize php-tests validator."""
super().__init__(action_type)
self.network_validator = NetworkValidator()
self.security_validator = SecurityValidator()
self.token_validator = TokenValidator()
def validate_inputs(self, inputs: dict[str, str]) -> bool:
"""Validate php-tests action inputs."""
valid = True
# Validate token (optional)
if inputs.get("token"):
token = inputs["token"]
valid &= self.validate_with(self.token_validator, "validate_github_token", token)
# Also check for variable expansion
if not self.is_github_expression(token):
valid &= self.validate_with(
self.security_validator, "validate_no_injection", token, "token"
)
# Validate email (optional, empty means use default)
if inputs.get("email"):
email = inputs["email"]
valid &= self.validate_with(self.network_validator, "validate_email", email, "email")
# Also check for shell metacharacters (but allow @ and .)
if not self.is_github_expression(email):
dangerous_chars = [";", "&", "|", "`", "$", "(", ")", "<", ">", "\n", "\r"]
if any(char in email for char in dangerous_chars):
self.add_error("email: Contains dangerous shell metacharacter")
valid = False
# Validate username (optional)
if inputs.get("username"):
username = inputs["username"]
if not self.is_github_expression(username):
valid &= self.validate_with(
self.security_validator, "validate_no_injection", username, "username"
)
if len(username) > 39:
self.add_error("Username is too long (max 39 characters)")
valid = False
return valid
def get_required_inputs(self) -> list[str]:
"""Get list of required inputs."""
return []
def get_validation_rules(self) -> dict:
"""Get validation rules for this action."""
rules_path = Path(__file__).parent / "rules.yml"
return self.load_rules(rules_path)