Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow overriding of host, port, protocol nsdr url path for URL building #175

Merged
merged 6 commits into from
Nov 15, 2016

Conversation

pitbulk
Copy link
Contributor

@pitbulk pitbulk commented Nov 13, 2016

A developer can use setSelfProtocol, setSelfHost, setSelfPort and getBaseURLPath to define a specific value to be returned by isHTTPS, getSelfHost, getSelfPort and getBaseURLPath. And define a setBasePath to be used on the getSelfURL and getSelfRoutedURLNoQuery to replace the data extracted from $_SERVER["REQUEST_URI"].

At the settings the developer will be able to set a 'baseurl' parameter that automatically will use setBaseURL to set values for setSelfProtocol, setSelfHost, setSelfPort and setBaseURLPath.

dhensby and others added 4 commits September 8, 2016 20:38
- Added ability to set custom host/port/protocol
- Updated test coverage to include testing HTTP_X_FORWARDED_PORT
- Split port detection into its own method
… parameter on the settings the Base URL to be used instead of guessing the URL of the currentURL where SAML messages are processed.
@pitbulk
Copy link
Contributor Author

pitbulk commented Nov 13, 2016

@dhensby, sorry for the delay, can you review this PR?

Copy link
Contributor

@dhensby dhensby left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One blocker and a few other suggestions

if (!empty($baseurl)) {
$baseurlpath = '/';
if (preg_match('#^https?:\/\/([^\/]*)\/?(.*)#i', $baseurl, $matches)) {
if (strpos($baseurl, 'https://') == False) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this needs to be type equality (===) and you should use false not False

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure

*/
public static function setBaseURLPath($baseurlpath)
{
if (!isset($baseurlpath) || empty($baseurlpath)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can just used empty as isset will only return false if $baseurlpath is explicitly null, but empty will return true for null anyway.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok

$baseurlpath = '/';
}

self::$_baseurlpath = '/'. ltrim(rtrim($baseurlpath, '/') . '/', '/');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you not do '/'.trim($baseurlpath, '/') . '/';

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanted to assure that all start and end with a /. What the reason for avoiding that?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Won't my suggestion have the same effect? Trim / off both ends then spend it to both?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

haha, yes, sorry, yesterday was so late when I reviewed that

Copy link
Contributor Author

@pitbulk pitbulk Nov 14, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ohh, when $baseurlpath ==> '/'

'/'.trim($baseurlpath, '/') . '/'; returns //
but '/'. ltrim(rtrim($baseurlpath, '/') . '/', '/'); returns /

I will use

        if (empty($baseurlpath) || $baseurlpath == '/') {
            $baseurlpath = '/';
        } else {
            self::$_baseurlpath = '/' . trim($baseurlpath, '/') . '/';
        }

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, good point and that solution is more readable too, so cool.

$selfURLhost = self::getSelfURLhost();
$selfURLNoQuery = $selfURLhost . $_SERVER['SCRIPT_NAME'];

if (!empty(self::getBaseURLPath())) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can't use empty with method in php < 5.5 so you need to assign a var first as the module supports 5.3+

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, I noticed that on travis

@@ -493,6 +564,17 @@ public static function getSelfRoutedURLNoQuery()
}
}

if (!empty(self::getBaseURLPath())) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code is repeated and could be pulled into a protected method and re-used

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Noted

@pitbulk
Copy link
Contributor Author

pitbulk commented Nov 13, 2016

Thanks, I will fix that.

@pitbulk
Copy link
Contributor Author

pitbulk commented Nov 14, 2016

any scenario we are not covering? Are we now ready to merge?

Copy link
Contributor

@dhensby dhensby left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me

@pitbulk pitbulk merged commit a18bb25 into master Nov 15, 2016
@patricknelson
Copy link

For the life of me, I can't seem to really figure out why on earth why Util::getSelfRoutedURLNoQuery() was setup to call ::buildWithBaseURLPath() here.

Also, why is it that ::getSelfRoutedURLNoQuery() strips out the entire request URI except for the last URL segment? This causes URL's like: https://domain/saml/acs to be converted to https://domain/acs (i.e. request URI becomes just that last segment) simply because your base path is / and thus you end up with an error resulting during response validation:

A valid SubjectConfirmation was not found on this Response

This is because the $currentURL (from here) now contains https://domain/acs even though the Recipient in SubjectConfirmationData contains the full URL and fails the check on this line: https://github.com/onelogin/php-saml/blob/master/lib/Saml2/Response.php#L306

It seems as if this is missing a thorough explanation for the thought process behind changing the request URI like this when generating the current URL. What am I missing here?

@patricknelson
Copy link

p.s. I first mentioned this here on this comment and tracked it down to this issue. silverstripe/silverstripe-activedirectory#104 (comment)

patricknelson added a commit to patricknelson/silverstripe-saml that referenced this pull request Aug 18, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants