Prestashop redirect not exact url - url

I need to redirect inaccurate URL to 404 page
What I mean:
Existing URL
http://something.com/2-sport-shoes
Inaccurate URL
http://something.com/2-dsajdhasudhas is redirected to http://something.com/2-sport-shoes as links share the same ID (2)
How in Prestashop do redirect inaccurate url to 404?

Solution
modification CategoryController
public function canonicalRedirection($canonical_url = '')
{
if (Tools::getValue('live_edit')) {
return;
}
if (!Tools::getValue('noredirect') && Validate::isLoadedObject($this->category)) {
$exact_url= parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
$link = $this->category->id . "-" . $this->category->link_rewrite;
if($exact_url != $link) {
Tools::redirect('index.php?controller=404');
}
}
}

Related

'this page can't be displayed' when using HTTPS

for some actions in my Grails application i need to use HTTPS protocol , so i made the below filter :
def filters = {
all(controller:'checkout', action:'onlinePayment') {
before = {
if (!request.isSecure() /*&& !Environment.isDevelopmentMode()*/) {
def url = "https://" + request.serverName + request.forwardURI
redirect(url: url, permanent: true)
return false
}
}
but when i try to access this action , i get this page can't be displayed as seen in the screenshot and i'm geting in chrome's console net::ERR_CONNECTION_REFUSED, are there any configurations i missed to be able to use HTTPS protocol ?

Yii. Checking url before redirecting to prevent attack

I have $returnUrl var from Form with controller/action in it:
<?=CHtml::hiddenField('returnUrl',
Yii::app()->urlManager->parseUrl(Yii::app()->request)
);?>
In controller i have something like this:
$returnUrl = Yii::app()->request->getPost('returnUrl');
$returnUrl = array($returnUrl);
$this->redirect($returnUrl);
But it also work then i change $returnUrl from controller/action to external site url. Ex: if i put http://google.com to $_POST['returnUrl'] instead of site/index yii redirect me to /http://google.com without any errors.
What is the best way to check $returnUrl before redirecting? How i can compare $returnUrl with my routes or controllers/actions?
Now i do next:
$returnUrl = Utils::sanitizeReturnUrl($returnUrl);
...
class Utils
{
public static function sanitizeReturnUrl($returnUrl)
{
if (!preg_match('~^([-a-z0-9_]+|[-a-z0-9_]+/[-a-z0-9_]+)+$~i', $returnUrl))
{
$returnUrl = Yii::app()->homeUrl;
}
return $returnUrl;
}
}
But may be exists more appropriate way
The proper way is to parse your returnUrl and remove the scheme (http:// or https://) and other insecure stuff.
<?php
$returnUrl = 'http://username:password#hostname/path?arg=value#anchor';
$returnUrl = sanitizeReturnUrl($returnUrl);
echo $returnUrl;
/**
* now you got:
* hostname/path?arg=value#anchor
*/
function sanitizeReturnUrl ($url)
{
$urlArray = parse_url($url);
$url = $urlArray['host'] . $urlArray['path'] . '?' . $urlArray['query'] . '#' . $urlArray['fragment'];
return $url;
}

Setting the redirect_uri in Asp.Net Identity

I am trying to set the redirect_uri for the facebook login with Asp.Net Identity. However, the GetExternalLogin REST method in the AccountController is only triggered if the redirect_uri is '/'. If I add anything else it does not trigger GetExternalLogin, the browser only shows error: invalid_request.
However the url contains the redirected parameter as it should e.g. if I add the redirect_uri as http://localhost:25432/testing
the response URL looks like this:
http://localhost:25432/api/Account/ExternalLogin?provider=Facebook&response_type=token&client_id=self&redirect_uri=http%3A%2F%2Flocalhost%3A25432%2Ftesting&state=0NctHHGq_aiazEurHYbvJT8hDgl0GJ_GGSdFfq2z5SA1
and the browser window shows: error: invalid_request
Any idea why this works only when redirecting to '/' but not to any other urlĀ“s?
For anyone else that might run into this issue: the problem is when you take (copy) the ApplicationOAuthProvider.cs from the Visual Studio SPA template and it is there where this code is:
public override Task ValidateClientRedirectUri(OAuthValidateClientRedirectUriContext context)
{
if (context.ClientId == _publicClientId)
{
var expectedRootUri = new Uri(context.Request.Uri, "/");
if (expectedRootUri.AbsoluteUri == context.RedirectUri)
{
context.Validated();
}
}
return Task.FromResult<object>(null);
}
This will obviously block any redirect_uri that doesn't look like http://localhost/ or http://example.com/ so for instance http://example.com/home won't work.
Now this below is the source for InvokeAuthorizeEndpointAsync in Katana which does all the work and you can see it calls into any custom OAuthProvider that might be registered for this MVC/Web API application (this registration typically happens in Startup.Auth.cs):
private async Task<bool> InvokeAuthorizeEndpointAsync()
{
var authorizeRequest = new AuthorizeEndpointRequest(Request.Query);
var clientContext = new OAuthValidateClientRedirectUriContext(
Context,
Options,
authorizeRequest.ClientId,
authorizeRequest.RedirectUri);
if (!String.IsNullOrEmpty(authorizeRequest.RedirectUri))
{
bool acceptableUri = true;
Uri validatingUri;
if (!Uri.TryCreate(authorizeRequest.RedirectUri, UriKind.Absolute, out validatingUri))
{
// The redirection endpoint URI MUST be an absolute URI
// http://tools.ietf.org/html/rfc6749#section-3.1.2
acceptableUri = false;
}
else if (!String.IsNullOrEmpty(validatingUri.Fragment))
{
// The endpoint URI MUST NOT include a fragment component.
// http://tools.ietf.org/html/rfc6749#section-3.1.2
acceptableUri = false;
}
else if (!Options.AllowInsecureHttp &&
String.Equals(validatingUri.Scheme, Uri.UriSchemeHttp, StringComparison.OrdinalIgnoreCase))
{
// The redirection endpoint SHOULD require the use of TLS
// http://tools.ietf.org/html/rfc6749#section-3.1.2.1
acceptableUri = false;
}
if (!acceptableUri)
{
clientContext.SetError(Constants.Errors.InvalidRequest);
return await SendErrorRedirectAsync(clientContext, clientContext);
}
}
await Options.Provider.ValidateClientRedirectUri(clientContext);
if (!clientContext.IsValidated)
{
_logger.WriteVerbose("Unable to validate client information");
return await SendErrorRedirectAsync(clientContext, clientContext);
}
var validatingContext = new OAuthValidateAuthorizeRequestContext(
Context,
Options,
authorizeRequest,
clientContext);
if (string.IsNullOrEmpty(authorizeRequest.ResponseType))
{
_logger.WriteVerbose("Authorize endpoint request missing required response_type parameter");
validatingContext.SetError(Constants.Errors.InvalidRequest);
}
else if (!authorizeRequest.IsAuthorizationCodeGrantType &&
!authorizeRequest.IsImplicitGrantType)
{
_logger.WriteVerbose("Authorize endpoint request contains unsupported response_type parameter");
validatingContext.SetError(Constants.Errors.UnsupportedResponseType);
}
else
{
await Options.Provider.ValidateAuthorizeRequest(validatingContext);
}
if (!validatingContext.IsValidated)
{
// an invalid request is not processed further
return await SendErrorRedirectAsync(clientContext, validatingContext);
}
_clientContext = clientContext;
_authorizeEndpointRequest = authorizeRequest;
var authorizeEndpointContext = new OAuthAuthorizeEndpointContext(Context, Options);
await Options.Provider.AuthorizeEndpoint(authorizeEndpointContext);
return authorizeEndpointContext.IsRequestCompleted;
}
This is key:
await Options.Provider.ValidateClientRedirectUri(clientContext);
So your solution is to change how the ValidateClientRedirectUri performs the validation - the default SPA implementation is, as you can see, very naive.
There's lots of ppl having issues with SPA mainly because it lacks any kind of useful information and I mean that both for ASP.NET Identity and OWIN stuff and with regards to what is going on within KnockoutJS implementation.
I wish Microsoft would provide more comprehensive docs for these templates because anyone who will try to do anything a bit more complex will run into issues.
I've spent hours on this, digging into OWIN (Katana) source code thinking it is the above implementation that blocks my redirect URIs but it was not, hopefully helps someone else too.
HTH
The problem is that GetExternalLogin registered as OAuthOptions.AuthorizeEndpointPath which used for app.UseOAuthBearerTokens(OAuthOptions). This configuration puts validation on arguments of endpoint.
if (!Uri.TryCreate(authorizeRequest.RedirectUri, UriKind.Absolute, out validatingUri))
{
// The redirection endpoint URI MUST be an absolute URI
}
else if (!String.IsNullOrEmpty(validatingUri.Fragment))
{
// The endpoint URI MUST NOT include a fragment component.
}
else if (!Options.AllowInsecureHttp &&
String.Equals(validatingUri.Scheme, Uri.UriSchemeHttp, StringComparison.OrdinalIgnoreCase))
{
// The redirection endpoint SHOULD require the use of TLS
}
And you should pass "Authorize endpoint request missing required response_type parameter" and
"Authorize endpoint request contains unsupported response_type parameter"
Based on the other answers, I changed the Validation code in ApplicationOAuthProvider.cs to just ensure that the redirect uri is on the same domain like so:
public override Task ValidateClientRedirectUri(OAuthValidateClientRedirectUriContext context)
{
if (context.ClientId == _publicClientId)
{
Uri expectedRootUri = new Uri(context.Request.Uri, "/");
if (context.RedirectUri.StartsWith(expectedRootUri.AbsoluteUri))
{
context.Validated();
}
}
return Task.FromResult<object>(null);
}

get absolute url on handle ressource request on blackberry

I use this method the get the urls of ressources contain on web page
public InputConnection handleResourceRequest(BrowserFieldRequest request) throws Exception
{
final String url = request.getURL();
return super.handleResourceRequest(request);
}
But, I made request.getURL(); it returns relative url and not the absolute url.
How can I change it to get the absolute URL?
When I run your code, it does return me absolute URLs, even when my web page contained relative links. That said, it wouldn't surprise me if sometimes, it doesn't. I haven't fully tested this code, but I would think you could try something like this.
Basically, you check to see if the URL is absolute, and if not, you assemble an absolute URL by using the parent BrowserField document URL:
ProtocolController controller = new ProtocolController(_browserField) {
public InputConnection handleResourceRequest(BrowserFieldRequest request) throws Exception {
String absoluteUrl = null;
URI uri = URI.create(request.getURL());
if (uri.isAbsolute()) {
absoluteUrl = request.getURL();
} else {
String docUrl = _browserField.getDocumentUrl();
String url = request.getURL();
if (url.startsWith("/")) {
// the URL is relative to the server root
URI docUri = URI.create(docUrl);
absoluteUrl = docUri.getScheme() + "://" + docUri.getHost() + url;
} else {
// the URL is relative to the document URL
absoluteUrl = docUrl + url;
}
}
System.out.println(" requesting: " + absoluteUrl);
return super.handleResourceRequest(request);
}
}
Again, for me, I was getting absolute URLs, so I couldn't easily test the code in the branch where the URL is relative. So, it's possible that I'm dropping a "/" somewhere, or not handling file:/// URLs properly.
But, this is a starting point, to workaround your problem.

PHP Oauth inside page TAB

My tab needs to know the date when a user becomes fan, so i've to ask for permissions. Despite facebook official documentation, i made it successfully and the user is redirected to the oauth dialog and after he confirms, back to the tab.
$user = $facebook->getUser();
if ($user)
{
$access_token = $facebook->getAccessToken();
$user_profile = $facebook->api('/me');
try
{
$likes = $facebook->api("/me/likes/pageid");
}
catch (FacebookApiException $e)
{
$user = null;
}
}
else
{
?>
<script type="text/javascript">
var oauth_url = 'https://www.facebook.com/dialog/oauth/';
oauth_url += '?client_id=<?=$app_id?>';
oauth_url += '&redirect_uri=' + encodeURIComponent('https://www.facebook.com/<?=$pageid?>?sk=app_<?=$app_id?>');
oauth_url += '&scope='
window.top.location = oauth_url;
</script>
<?
die();
}
All works, but i'm not able to parse the error response in case users don't accept the dialog.
The returning url is:
https://www.facebook.com/page?sk=app_appid&error_reason=user_denied&error=access_denied&error_description=The+user+denied+your+request.#_=_
But the iframe inside tab doesn't have any parameters.
What can i do?
You can only pass data to the iframe on the tab using the app_data parameter in the URL. You will have to redirect unsuccessful login attempts to a URL like:
https://www.facebook.com/{your_page}?v=app_{app_id}&app_data={your_string}
E.g. https://www.facebook.com/{your_page}?v=app_{app_id}&app_data=login_failed
The login_failed still will appear in the decoded signed_request

Resources