CherryPy terminates session after $window.location.href - javascript

For a Django 1.8 app with Angular.js & Django Rest Framework I'm using CherryPy server to serve the app over WSGI.
For this purpose I'm basically reusing this code, which works fine, until I use the following angular.js command in one of my *.js files:
url = patientDetailView + response.data.id + '/';
$window.location.href=url;
The view this link is pointing to requires (like other views as well) the user to be logged in(authenticated). However, although the user has been already logged in after $window.location.href=url django redirects to the login screen where the user needs to log-in again! My guess is that this may be due to the session being terminated (?). I don't see this problem while running the django dev server (./manage.py runserver)
Anybody can point me to why this is happening and how to fix that? I'm running out of ideas...

Related

Silent Renewal in Ionic 3 with Identity Server 4

So I am trying to implement silent renewal in an ionic 3 application, I am still learning about the whole thing so I'll try to be as descriptive as possible please correct me if I am wrong.
Authentication
I am using Implicit flow for my authentication using the In App Browser.
The user is redirected to the authentication server page
After a success authentication I retrieve the id-token & access-token
As I understand the id-token is for authentication and access-token is for authorization with the API.
I have followed this article to help me set this up (Particularly the "Deploy to Mobile Device" section) for my Identity Server.
As done in the article I am using angular-oauth2-oidc to assist me with storing information about redirect links, issuer, etc...
I have attempted to achieve this in 3 different ways, 2 of them work but I don't understand how to retrieve the new access-token and id-token, and the last one returns an error. each of them left me with questions.
First: oauthService
The angular-oauth2-oidc library has a silentRefresh() method, and this github MD describes how to use it using a hidden iframe very vaguely so I barely understand how this works. I have created a silent-refresh.html page in the same directory, but using http://localhost:8000/silent-refresh.html return's a 404. Calling the silentRefresh() method successfully re-authenticates on the server side but the request times-out on the client side, as said in the MD file, something is wrong with the iframe.
Question 1: Does the library create a new iframe and then waits for a response to the http://localhost:8000/silent-refresh.html page but is never found so I never get my response? How to proceed to retrieve my tokens?
Second: iframe
So here I follow this article where I create an iframe and add it to the body. I create my own url (similar to the one made by the silentRefresh() method), and assign it to the src of the iframe. Again on the server side everything is fine and it tries to return the tokens to http://localhost:8000.
public startRenew(url: string) {
this._sessionIframe.src = url;
return new Promise((resolve) => {
this._sessionIframe.onload = () => {
resolve();
}
});
}
Question 2: How to proceed to retrieve the tokens? as it doesn't update my tokens automatically, and I don't see how the code above can do it.
Third: In App Browser
I thought this would work fine as I already know how to process the request using the In App Browser. So I tried to use the same url that worked for the iframe in the 2nd part. However this returns an error: prompt=none was requested. But user is not authenticated. on the server side, which tells that the server can't find the session so it doesn't know who is requesting the token renewal.
Question 3: Is there a specific reason this won't work other than I made a mistake?
NOTE: Took longer than expected to write this will edit this in a bit.
oAuthService
So I looked in to the implementation of the silent refresh, to see what it does. It creates an iframe with a default id, unless you override it. That cleared up a lot of confusion as to what was actually happening.
The next mistake I did was placing the silent-refresh.html file in the src/ folder, that makes it inaccessible to the iframe. Instead the file should have been placed in the www/ folder.
Then inside the iframe I kept getting the net::ERR_CONNECTION_REFUSED error. This was due to CORS and is solved by editing the Client int the Config.cs file on the Authentication Server:
AllowedCorsOrigins = { "http://localhost:8100", "http://<ip>:8100/", "http://<ip>:8100/silent-refresh.html" },
WARNING: This didn't work once I wanted to take this outside serving in the browser (ionic serve) or emulating on my device with ionic cordova run android -c-l-s, these made the root url return something like http://<ip>/. But once ran with ionic cordova run android (without the flags), window.location.href would return file:///<example>/<something>/index.html, using this sort of path (file:///<example>/<something>/silent-refresh.html) as a redirect url caused an ERR_UNSAFE_REDIRECT error to display in the iframe.
Perhaps silentRefresh() is an Angular only solution?
In App Browser
The mistake that caused the original error was having clearsessioncache and clearcache set to yes when creating the browser, caused the session to be wiped so the authentication server didn't know who it was duh, now reduced to this:
const browser = window.cordova.InAppBrowser.open(oauthUrl, '_blank',
'location=no, hidden=yes'
);
Regular redirect url of http://localhost:8100 could be used to catch the request with the new tokens. And the silent-refresh.html page is not needed.
Here is the code for creating the oauthUrl:
buildOAuthRefreshUrl(nonce): string {
return this.oauthService.issuer + '/connect/authorize?' +
'response_type=id_token%20token' +
'&client_id=' + this.oauthService.clientId +
'&state=' + nonce +
'&redirect_uri=' + encodeURIComponent(this.oauthService.redirectUri) +
'&scope=' + encodeURI(this.oauthService.scope) +
'&nonce=' + nonce +
'&prompt=none';
}
The rest of the code is pretty much identical to the originally mentioned article

Soundcloud auth popup callback.html never closes after connecting

I'm using Soundclouds JS sample code for client side JS apps to connect with the Soundcloud API, as a start. The only difference between their code and mine is I've put in my own client_id and redirect_uri. (I also copied their callback.html, put it on my server, put its address in the soundcloud page for my app).
After ok-ing with my popup blocker, the auth popup comes up and asks permission to access my account, I give it permission, then the popup clears all previous content and simply informs: 'This popup should automatically close in a few seconds' - but it doesn't, and the rest of the code that shows its past authorization never displays.
Here is Soundclouds sample that I'm using. I've tried it while using a server on localhost and also deploying it and changing redirect_uri appropriately with the exact same results.
SC.initialize({
client_id: 'YOUR_CLIENT_ID', // changed it to mine
redirect_uri: 'http://example.com/callback'
});
SC.connect().then(function() {
return SC.get('/me');
}).then(function(me) {
alert('Hello, ' + me.username);
});
Looking in the dev console on both Chrome and Firefox, I dont see any errors. I've also made sure the protocol for my redirect_uri file matches between my account settings and the code.
Does the 'Website of your app' field on the Soundcloud page for my app make a difference? I tried setting it, it didnt fix it. What does client secret do?
The closest to an answer I've found so far is from this SO page where it seems he found out that you can't use an url that doesn't start with 'www.' ??? Its hard for me to believe that this is the problem and unfortunately for me neither localhost or my domain start with www.
Thanks in advance for any help.
In your callback.html, change the line:
<body onload="window.opener.setTimeout(window.opener.SC.connectCallback, 1)">
to:
<body onload="window.setTimeout(window.opener.SC.connectCallback, 1)">
In your application setup page at soundcloud.com, ensure your website setting and callback uri are on the same domain (whether that is localhost or the production domain) and all should work.
Note: for debugging, comment out this line to leave the popup there deliberately, then console can be used to interrogate other code in the callback.html page.

Django-cms installs, but pull-downs and other JS doesn't work - ideas for fixing?

I've installed Django-CMS onto an existing site and while it isn't throwing errors, it isn't working. In particular, the header on a given page appears when I use "/?edit" but none of the pull down menus work, and very little (possibly none) of the JavaScript works.
Other facets:
I've done this on a local install of Django with largely development components (for example, SQLite, and the server provided via the django tutorial)
I've done this with the same result on an install on WebFactional using MySQL and an apache server
The install is basically the process described here:
http://docs.django-cms.org/en/support-3.0.x/how_to/install.html
The DB install worked w/out errors and the /admin site has a section for CMS
The CMS check showed 1 test skipped, and all other tests passed.
I'm using Django 1.6.5
This isn't the only time I've had trouble getting django to deliver javascript in a way that executes properly on a project - I had problems with fairly simple drop down menus in the past that I never resolved.
Any ideas on what I could be doing wrong? My configuration changes could be seen here:
https://github.com/bethlakshmi/GBE2/compare/GBE-398
The Local Settings (recent edit)
DEBUG = True
TEMPLATE_DEBUG = False
ALLOWED_HOSTS = ['*domain of server*']
LOGIN_REDIRECT_URL = '/'
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': '*db name*',
'USER': '*username*',
'PASSWORD': '*password*',
'HOST': '',
'PORT': '',
}
}
STATIC_ROOT = '*path to the static host in the file system*'
#STATIC_ROOT = '/'
EMAIL_HOST = '* email settings*'
EMAIL_HOST_USER = '*email settings*'
EMAIL_HOST_PASSWORD = '*email settings*'
DEFAULT_FROM_EMAIL = '*valid email*'
SERVER_EMAIL = '*valid email*'
domain of server - the site is hosted on a subdomain: - prototypecms.gbeadmin.webfactional.com, the Allowed Host is "gbeadmin.webfactional.com"
db name, username, password - the correct settings for the locally hosted database. The website itself works just fine with these database settings. I can log in with the same info using PHP Admin from the console. And when I look in the DB, I see the cms_* tables that came from django-cms during a syncdb.
path to the static host in the file system - its a valid location in the server's file system. The CSS and JS are there and when I download the source page in the browser and look at /static links it references, I get the correct JS or CSS that I would expect from the server. The host recommends a particular separate area for static files and a particular configuration - which I've followed and gotten working successfully in the pre-django-cms application. If it wasn't working, I believe the CSS would not render correctly, and it works fine.
email settings - are the email settings for the server. Right now they are not working and need to be tested and fixed, but I have a large amount of doubt that email settings could be a factor here.
valid email the various email settings used by django in creating a mail. These are valid addresses relevant to the business.
After staring at this for about 1.5 weeks, I think I found the answer.
The eventual process to the solution was to get the tutorial up and running in the same environment and start slavishly comparing settings and templates. With a working tutorial, I could see what was there and slavishly imitate it.
The settings.py and local_settings.py was a rat hole - they worked just fine.
Eventual answer was that the pre-existing site and django-cms were contending over base.html and the block for "content" - there was a mapping for "/" in the base site urls and that meant that it didn't connect to a template, and it didn't have any content blocks. This really seemed to confuse Django-CMS site to the point where it would offer no pulldowns. Once I got base.html (now base.tmpl) to more closely imitate the tutorial, I was able to get the pull downs working.
The commit of the original solution was:
https://github.com/bethlakshmi/GBE2/commit/8286a9afd6e3ba8688dfefc4c9d888f5a2fd320f
And on the branch here:
https://github.com/bethlakshmi/GBE2/tree/GBE-398
There have been many more refinements.
The areas to look at would be gbe/base.tmpl, and also the landing and landing_page areas as the first thing that got executed was predictably the url resolution of "/" - so that was a particular blocker.
This is the leap forward I needed, but still a partial solution as there is a massive amount of integration yet to be done here.

API calls are not working in cordova application

I made an application using apache cordova. my server is written in node.js running locally and port 3005. So I want to make API call from cordova I am using backbone in client side.
I written the following code to make API call
makingAPICallForStatus:function(){
var userSessionModel = Backbone.Model.extend({ //Creaating a model for checking user session status
url:"http://localhost:3005/api/user/status/",
});
var userSessionModelObj=new userSessionModel();
this.makeApiCall(userSessionModelObj,"",'GET',function(model,response,options){console.log(response);});
},
makeApiCall:function(modelObj,dataObject,requestType,successCallback){
modelObj.fetch({data:dataObject,
type:requestType,
success:successCallback,
error:function(){console.log("error")}
});
}
If you observe, I mention URL path is :"http://localhost:3005/api/user/status/". This way it's not working. it's showing This request has no response data available
Now I tried with production domain like
URL path is :"http://xxx.xxxx.com/api/user/status/"
This way it's working fine.
Why localhost was not working, I invoke same url directly in my browser working fine. but it's not working in cordova.
Note : I didn't modify anything in www/config.xml file.
What's the problem how can I fix this.
Thanks.
localhost is an alias of 127.0.0.1 even if you are running on an emulator on the same machine, local host is not real. You have to always make calls to an ipaddress or domain name from a device (even virtual devices). This is because on the device localhost is referring to the device not the machine that it may be running from.

How do I test an externally served app using Testacular + AngularJS

I have an app running on http://localhost:6543 - it's a Pyramid app.
This app serves the AngularJS app at /
This app uses socket.io itself
The question is: is it possible to test that application using those tools ?
I have this in my scenario.js file:
beforeEach(function() {
browser().navigateTo('http://localhost:6543/');
});
but the moment I launch testacular (with run or start), I get this error message:
Chrome 23.0 registration: should delete all cookies when user clicks on "remove all" button FAILED
browser navigate to 'http://localhost:6543/'
/home/abourget/myapp/jstests/scenarios/registration_scenario.js:9:5: Sandbox Error: Application document not accessible.
so I understand the browser doesn't give access to the iframe's document, because it'd be some Cross-Origin violation.
What I tried:
Proxying to my app using the Testacular web server (with the proxies option), but / would conflict with Testacular's own serving of its framework. Also, both apps would eventually try to use /socket.io and that would conflict also.
Doing the reverse (tweaking my app to proxy to Testacular's server), but then, we'd get the same issues with /socket.io.
Thanks for these great tools, btw!
Instead of having
beforeEach(function() {
browser().navigateTo('http://localhost:6543/');
});
change this to
beforeEach(function() {
browser().navigateTo('/');
});
and then in your testacular-e2e.conf.js file add:
proxies = {
'/': 'http://localhost:6543/'
};
You might still have other issues, but I can reproduce the "Sandbox Error: Application document not accessible." message with just the Pyramid Hello World App and this configuration problem.
We had a similar problem, and had already proxies and navigateTo('/'). We needed to add some urlRoot to avoid conflicts when loading socket.io. We simply added '/e2e' and that was enough to solve the conflict. Actually, there was a warning message when running testacular for this issue.

Categories

Resources