Skip to content

Commit

Permalink
ENH Use symfony/validation logic (#167)
Browse files Browse the repository at this point in the history
  • Loading branch information
GuySartorelli authored Oct 2, 2024
1 parent 450be05 commit df87533
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 30 deletions.
9 changes: 6 additions & 3 deletions src/RealMeService.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,15 @@
use SilverStripe\Core\Environment;
use SilverStripe\Core\Injector\Injectable;
use SilverStripe\Core\Injector\Injector;
use SilverStripe\Core\Validation\ConstraintValidator;
use SilverStripe\RealMe\Exception as RealMeException;
use SilverStripe\RealMe\Model\FederatedIdentity;
use SilverStripe\RealMe\Model\User;
use SilverStripe\Security\Member;
use SilverStripe\Security\Security;
use SilverStripe\View\TemplateGlobalProvider;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\Url;

class RealMeService implements TemplateGlobalProvider
{
Expand Down Expand Up @@ -458,11 +461,11 @@ public function enforceLogin(HTTPRequest $request, $backUrl = null)
}

$backUrl = $this->validSiteURL($backUrl);

if (!$backUrl) {
$backUrl = Director::absoluteBaseURL();
}

// If not, attempt to retrieve authentication data from OneLogin (in case this is called during SAML assertion)
try {
if (!$session->get("RealMeErrorBackURL") && Controller::has_curr()) {
Expand Down Expand Up @@ -800,7 +803,7 @@ public function getAssertionConsumerServiceUrlForEnvironment($env)
}

$domain = $this->getMetadataAssertionServiceDomainForEnvironment($env);
if (filter_var($domain, FILTER_VALIDATE_URL) === false) {
if (!ConstraintValidator::validate($domain, [new Url(), new NotBlank()])->isValid()) {
return null;
}

Expand Down
45 changes: 18 additions & 27 deletions src/Task/RealMeSetupTask.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,14 @@
use SilverStripe\RealMe\RealMeService;
use SilverStripe\Control\Director;
use SilverStripe\Control\Controller;
use SilverStripe\Core\Validation\ConstraintValidator;
use SilverStripe\Dev\BuildTask;
use SilverStripe\PolyExecution\PolyOutput;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\Url;

/**
* Class RealMeSetupTask
Expand Down Expand Up @@ -275,45 +278,33 @@ private function validateEntityID($forEnv)
);
}

// make sure the entityID is a valid URL
$entityId = filter_var($entityId, FILTER_VALIDATE_URL);
if ($entityId === false) {
$this->errors[] = _t(
RealMeSetupTask::class . '.ERR_CONFIG_ENTITYID',
'The Entity ID (\'{entityId}\') must be https, not be \'localhost\', and must contain a valid ' .
'service name and privacy realm e.g. https://my-realme-integration.govt.nz/p-realm/s-name',
array(
'entityId' => $entityId
)
);

$validationMessage = _t(
RealMeSetupTask::class . '.ERR_CONFIG_ENTITYID',
'The Entity ID (\'{entityId}\') must be https, not be \'localhost\', and must contain a valid ' .
'service name and privacy realm e.g. https://my-realme-integration.govt.nz/p-realm/s-name',
['entityId' => $entityId]
);
// make sure the entityID is a valid URL with HTTPS protocol
if (!ConstraintValidator::validate($entityId, [new Url(protocols: ['https']), new NotBlank()])->isValid()) {
$this->errors[] = $validationMessage;
// invalid entity id, no point continuing.
return;
}

// check it's not localhost and HTTPS. and make sure we have a host / scheme
// check it's not localhost
$urlParts = parse_url($entityId ?? '');
if ($urlParts['host'] === 'localhost' || $urlParts['scheme'] === 'http') {
$this->errors[] = _t(
RealMeSetupTask::class . '.ERR_CONFIG_ENTITYID',
'The Entity ID (\'{entityId}\') must be https, not be \'localhost\', and must contain a valid ' .
'service name and privacy realm e.g. https://my-realme-integration.govt.nz/p-realm/s-name',
array(
'entityId' => $entityId
)
);

if ($urlParts['host'] === 'localhost') {
$this->errors[] = $validationMessage;
// if there's this much wrong, we want them to fix it first.
return;
}

$path = ltrim($urlParts['path'] ?? '');
$urlParts = preg_split("/\\//", $path ?? '');

$pathParts = preg_split("/\\//", $path ?? '');

// A valid Entity ID is in the form of "https://www.domain.govt.nz/<privacy-realm>/<service-name>"
// Validate Service Name
$serviceName = array_pop($urlParts);
$serviceName = array_pop($pathParts);
if (mb_strlen($serviceName ?? '') > 20 || 0 === mb_strlen($serviceName ?? '')) {
$this->errors[] = _t(
RealMeSetupTask::class . '.ERR_CONFIG_ENTITYID_SERVICE_NAME',
Expand All @@ -327,7 +318,7 @@ private function validateEntityID($forEnv)
}

// Validate Privacy Realm
$privacyRealm = array_pop($urlParts);
$privacyRealm = array_pop($pathParts);
if (null === $privacyRealm || 0 === mb_strlen($privacyRealm ?? '')) {
$this->errors[] = _t(
RealMeSetupTask::class . '.ERR_CONFIG_ENTITYID_PRIVACY_REALM',
Expand Down

0 comments on commit df87533

Please sign in to comment.