package Validator; use Logging; use XmlNode; use Exception::XmlNode; sub validateCpAccountNode { my $cpAccountNode = shift; verifyAttributeExists($cpAccountNode, 'name'); verifyAttributeExists($cpAccountNode, 'home'); verifyChild($cpAccountNode,'suspended', 0, 1); my @cpLimitNodes = $cpAccountNode->getChildren('limit'); foreach my $cpLimitNode ( @cpLimitNodes ) { verifyAttributeExists($cpLimitNode, 'name'); verifyAttributeToken($cpLimitNode, 'name','disk_space','max_subdom','max_box','max_ftpusers','max_parked','max_db','max_maillists','max_traffic','max_addon','max_accounts'); } my @cpPermissionNodes = $cpAccountNode->getChildren('permission'); foreach my $cpPermissionNode ( @cpPermissionNodes ) { verifyAttributeExists($cpPermissionNode, 'name'); verifyAttributeToken($cpPermissionNode, 'name','create_accounts','create_domains','manage_dns'); } my @cpFeatureNodes = $cpAccountNode->getChildren('feature'); foreach my $cpFeatureNode ( @cpFeatureNodes ) { verifyAttributeExists($cpFeatureNode, 'name'); verifyAttributeToken($cpFeatureNode, 'name','cron','lists','password','parkeddomains','rawlog','subdomains','backup','ftpsetup','addondomains','statmanager','spamassassin','clamavconnector_scan'); verifyAttributeExists($cpFeatureNode, 'allowed'); verifyAttributeToken($cpFeatureNode, 'allowed','true','false'); } verifyChild($cpAccountNode,'spamassassin', 0, 1); verifyChild($cpAccountNode,'ip', 0, 1); verifyChild($cpAccountNode,'domain', 1, 1); validateCpDomainNode($cpAccountNode->getChild( 'domain' ) ); return; } sub validateCpDomainNode { my $cpDomainNode = shift; verifyAttributeExists($cpDomainNode, 'name'); verifyAttributeExists($cpDomainNode, 'www_root'); verifyChild($cpDomainNode,'anonftp', 0, 1); my $cpAnonftpNode = $cpDomainNode->getChild('anonftp'); if ( defined ( $cpAnonftpNode ) ) { verifyAttributeToken($cpAnonftpNode, 'pub', 'true', 'false'); verifyAttributeToken($cpAnonftpNode, 'incoming', 'true', 'false'); } verifyChild($cpDomainNode,'ftpuser', 1); my @cpFtpuserNodes = $cpDomainNode->getChildren('ftpuser'); foreach my $cpFtpuserNode ( @cpFtpuserNodes ) { verifyAttributeExists($cpFtpuserNode, 'name'); } my @cpPdirNodes = $cpDomainNode->getChildren('pdir'); foreach my $cpPdirNode ( @cpPdirNodes ) { verifyAttributeExists($cpPdirNode, 'name'); my @cpPduserNodes = $cpPdirNode->getChildren('pduser'); foreach my $cpPduserNode ( @cpPduserNodes ) { verifyAttributeExists($cpPduserNode, 'name'); verifyAttributeToken($cpPduserNode, 'encoding','plain','base64'); } } my @cpSubdomainNodes = $cpDomainNode->getChildren('subdomain'); foreach my $cpSubdomainNode ( @cpSubdomainNodes ) { validateCpSubdomainNode ( $cpSubdomainNode ); } my @cpAddondomainNodes = $cpDomainNode->getChildren('addondomain'); foreach my $cpAddondomainNode ( @cpAddondomainNodes ) { validateCpAddondomainNode ( $cpAddondomainNode ); } verifyChild($cpDomainNode,'mail', 0, 1); my $cpMailNode = $cpDomainNode->getChild( 'mail' ); validateCpMailNode($cpMailNode) if ( defined ( $cpMailNode ) ); my @cpDatabaseNodes = $cpDomainNode->getChildren('database'); foreach my $cpDatabaseNode ( @cpDatabaseNodes ) { validateCpDatabaseNode ( $cpDatabaseNode ); } verifyChild($cpDomainNode,'maillists', 0, 1); my $cpMaillistsNode = $cpDomainNode->getChild( 'maillists' ); if ( defined ( $cpMaillistsNode ) ) { my @cpMaillistNodes = $cpMaillistsNode->getChildren('maillist'); foreach my $cpMaillistNode ( @cpMaillistNodes ) { validateCpMaillistNode ( $cpMaillistNode ); } } return; } sub validateCpSubdomainNode { my $cpSubdomainNode = shift; verifyAttributeExists($cpSubdomainNode, 'name'); verifyAttributeExists($cpSubdomainNode, 'www_root'); verifyChild($cpSubdomainNode,'ftpuser', 0, 1); my $cpSubdomainFtpUser = $cpSubdomainNode->getChild( 'ftpuser' ); verifyAttributeExists($cpSubdomainFtpUser, 'name') if defined ( $cpSubdomainFtpUser ); my @cpAddondomainNodes = $cpSubdomainNode->getChildren('addondomain'); foreach my $cpAddondomainNode ( @cpAddondomainNodes ) { validateCpAddondomainNode ( $cpAddondomainNode ); } verifyChild($cpSubdomainNode,'mail', 0, 1); my $cpMailNode = $cpSubdomainNode->getChild( 'mail' ); validateCpMailNode($cpMailNode) if ( defined ( $cpMailNode ) ); return; } sub validateCpAddondomainNode { my $cpAddondomainNode = shift; verifyAttributeExists($cpAddondomainNode, 'name'); verifyChild($cpAddondomainNode,'mail', 0, 1); my $cpMailNode = $cpAddondomainNode->getChild( 'mail' ); validateCpMailNode($cpMailNode) if ( defined ( $cpMailNode ) ); return; } sub validateCpMailNode { my $cpMailNode = shift; my $cpDefaultNode = $cpMailNode->getChild( 'default' ); verifyAttributeToken($cpDefaultNode, 'target','email','fail', 'ignore') if ( defined ( $cpDefaultNode ) ); my @cpMailnameNodes = $cpMailNode->getChildren('mailname'); foreach my $cpMailnameNode ( @cpMailnameNodes ) { validateCpMailnameNode( $cpMailnameNode ); } my @cpForwardNodes = $cpMailNode->getChildren('forward'); foreach my $cpForwardNode ( @cpForwardNodes ) { verifyAttributeExists($cpForwardNode, 'mailname'); verifyAttributeExists($cpForwardNode, 'redirect'); } my @cpAutoresponderNodes = $cpMailNode->getChildren('autoresponder'); foreach my $cpAutoresponderNode ( @cpAutoresponderNodes ) { verifyAttributeExists($cpAutoresponderNode, 'mailname'); verifyAttributeToken($cpAutoresponderNode, 'type','plain','html'); } return; } sub validateCpSpamassassinNode { my $cpSpamassassinNode = shift; verifyAttributeToken($cpSpamassassinNode, 'status', 'off', 'on'); verifyAttributeToken($cpSpamassassinNode, 'action', 'del', 'mark'); return; } sub validateCpMailnameNode { my $cpMailnameNode = shift; verifyAttributeExists($cpMailnameNode, 'name'); verifyAttributeExists($cpMailnameNode, 'password'); verifyChild($cpMailnameNode, 'spamassassin', 0, 1); my $cpSpamassassinNode = $cpMailnameNode->getChild( 'spamassassin' ); if ( defined ( $cpSpamassassinNode ) ) { validateCpSpamassassinNode($cpSpamassassinNode); } return; } sub validateCpDatabaseNode { my $cpDatabaseNode = shift; verifyAttributeExists($cpDatabaseNode, 'name'); verifyAttributeExists($cpDatabaseNode, 'type'); verifyAttributeToken($cpDatabaseNode, 'type', 'mysql', 'postgresql'); my @cpDbuserNodes = $cpDatabaseNode->getChildren('dbuser'); foreach my $cpDbuserNode ( @cpDbuserNodes ) { verifyAttributeExists($cpDbuserNode, 'name'); verifyChild($cpDbuserNode, 'password', 1, 1); verifyAttributeExists($cpDbuserNode->getChild('password'), 'type'); verifyAttributeToken($cpDbuserNode->getChild('password'), 'type','plain','encrypted'); } return; } sub validateCpMaillistNode { my $cpMaillistNode = shift; verifyAttributeExists($cpMaillistNode, 'name'); verifyChild($cpMaillistNode, 'owner', 1); verifyChild($cpMaillistNode, 'password', 0, 1); my $cpPasswordNode = $cpMaillistNode->getChild( 'password' ); if ( defined ( $cpPasswordNode ) ) { verifyAttributeExists($cpPasswordNode, 'type'); verifyAttributeToken($cpPasswordNode, 'type','plain','encrypted'); } verifyChild($cpMaillistNode, 'owner', 1); return; } # # Begin routines that verify xmlNode with throwing Exception::XmlException # Examples: # verifyAttributeToken($xmlNode,'name', 'true', 'false'); # verifyAttributeExists($xmlNode, 'name'); # verifyChild($xmlNode,'domain', 1, 1); # verifyChild routine # Examples: # verifyChild($xmlNode, 'element-name', 0, 1) => minOccurs="0" maxOccurs="1" (default) # verifyChild($xmlNode, 'element-name', 1, 1) => minOccurs="1" (default) maxOccurs="1" (default) # verifyChild($xmlNode, 'element-name', 1) => minOccurs="1" maxOccurs="unbounded" # sub verifyChild { my ($xmlNode, $child, $minOccurs, $maxOccurs) = @_; unless ( ref($xmlNode) =~ /XmlNode/ ) { throw Exception::XmlNode(undef,"No XmlNode passed"); } unless ( $child ) { Logging::error("Try check existence for unspecified child"); return; } my @childNodes = $xmlNode->getChildren( $child ); if ( ( $minOccurs > 0 ) and (scalar(@childNodes) == 0) ) { throw Exception::XmlNode( $xmlNode->copy(),"Invalid XmlNode. Element '".$xmlNode->getName()."'","Child element '".$child."' is required but isn't found"); } if ( ( $maxOccurs == 1 ) and (scalar(@childNodes) > 1) ) { throw Exception::XmlNode( $xmlNode->copy(),"Invalid XmlNode. Element '".$xmlNode->getName()."'","Multiple child elements '".$child."' found that is not allowed"); } return; } sub verifyAttributeExists { my ($xmlNode, $attribute) = @_; unless ( ref($xmlNode) =~ /XmlNode/ ) { throw Exception::XmlNode(undef,"No XmlNode passed"); } unless ( defined ( $attribute ) ) { Logging::error("Try check existence for attribute 'undef'"); return; } unless ( defined ($xmlNode->getAttribute( $attribute ) ) ) { throw Exception::XmlNode( $xmlNode->copy(),"Invalid XmlNode. Element '".$xmlNode->getName()."'","Attribute '".$attribute."' is required but isn't found"); } return; } sub verifyAttributeToken { my $xmlNode = shift; my $attribute = shift; my $tokenArray = \@_; unless ( ref($xmlNode) =~ /XmlNode/ ) { throw Exception::XmlNode(undef,"No XmlNode passed"); } unless ( defined ( $attribute ) ) { Logging::error("Try check existence for attribute 'undef'"); return; } my $attributeValue = $xmlNode->getAttribute( $attribute ); if ( defined ( $attributeValue ) ) { foreach my $tokenItem ( @$tokenArray ) { if ( $tokenItem eq $attributeValue ) { return; } } throw Exception::XmlNode($xmlNode->copy(),"Invalid XmlNode. Element '".$xmlNode->getName()."'","Attribute '".$attribute."' has invalid value ('".$attributeValue."')","Possible values are: @$tokenArray"); } return; } # # End of routines that verify xmlNode # 1;