Loosing session between requests in Play 1.2.2 - session

I'm having a really odd issue. I'm reusing a piece of code that was fully functional in a previous project but now fails. The code does something like this (code simplified to minimal failing scenario):
if (OpenID.isAuthenticationResponse()) {
UserInfo verifiedUser = OpenID.getVerifiedID();
String value = session.get(AppKeys.AUTH_METHOD); << ERROR
Application.index();
} else {
OpenID openid = getOpenId(client);
session.put(AppKeys.AUTH_METHOD, value);
if (!openid.verify()) {
Application.index();
}
}
Previously I could retrieve the value in the line marked as ERROR. Now that line sets value to null. I've done some tests and, somehow, the session values are lost during the requests although the session id is the same always (so the session in itself doesn't get lost).
I'm sure there is some configuration I've broken, but I'm not being able to find which one. Anyone knows?

In one of those situations of "find the answer just as you sent the question" I discovered the issue. This was the setting screwing the process:
# application.defaultCookieDomain=.xxxxx.com
As I'm in localhost the cookie was not retrieved, and in Play the session values are stored in the cookie as Play is stateless.
Yes, it's time to go to bed...

Related

How to serialize a SecTrustRef object?

I have a SecTrustRef object from the system that I'd like to evaluate myself. Just calling SecTrustEvaluateAsync will be sufficient for this job. The problem is, I must evaluate it in a different process as only this other process has access to the keychains where the CA certificates are stored that may cause evaluation to succeed.
The two processes have an IPC link that allows me to exchange arbitrary byte data between them but I don't see any way to easily serialize a SecTrustRef into byte data and deserialize that data back to an object at the other process. There doesn't seem to be a persistent storage mechanism for SecTrustRef.
So am I overlooking something important here, or do I really have to get all the certs (SecTrustGetCertificateAtIndex) and all the policies (SecTrustCopyPolicies) and serialize these myself?
And if so, how would I serialize a policy?
For the certificate (SecCertificateRef) it's rather easy, I just call SecCertificateCopyData and later on SecCertificateCreateWithData.
But for policies I can only call SecPolicyCopyProperties on one side and later on SecPolicyCreateWithProperties, however the later one requires a 2nd parameter, a policyIdentifier and I see no way to get that value from an existing policy. What am I missing?
Reading through the source of the Security framework, I finally figured it out how to copy a SecPolicyRef:
SecPolicyCreateWithProperties wants what it calls a "policyIdentifier". It's a constant like kSecPolicyAppleIPsec.
This does not get stored directly by the function, it's comparing the value and calling dedicated internal "initializers" (like SecPolicyCreateIPsec).
These in turn call SecPolicyCreate (which is private). They end up passing the same identifier value that you passed to SecPolicyCreateWithProperties.
And this value then gets stored as-is in the _oid field!
The identifier is actually the OID. You can get it either via SecPolicyCopyProperties(policy) (stored in the dictionary with key kSecPolicyOid) or via SecPolicyGetOID (but that returns it as an inconvenient CSSM_OID). Some of those specialized initializers also use values from the properties dictionary passed to SecPolicyCreateWithProperties, those should be present in the copied properties dictionary already.
So this gives us:
Serialization:
CFDictionaryRef createSerializedPolicy(SecPolicyRef policy) {
// Already contains all the information needed.
return SecPolicyCopyProperties(policy);
}
Deserialization:
SecPolicyRef createDeserializedPolicy (CFDictionaryRef serialized) {
CFStringRef oid = CFDictionaryGetValue(serialized, kSecPolicyOid);
if (oid == NULL || CFGetTypeID(oid) != CFStringGetTypeID()) {
return NULL;
}
return SecPolicyCreateWithProperties(oid, serialized);
}
To reproduce the original SecTrustRef as closely as possible, the anchors need to be copied as well. There is an internal variable _anchorsOnly which is set to true once you set anchors. Unfortunately, there is no way to query this value and I've seen it being false in trusts passed by NSURLSession, for example. No idea yet on how to get this value in a public way.
Another problematic bit are the exceptions: if _exceptions is NULL but you query them via SecTrustCopyExceptions(trust), you do get data! And if you assign that to the deserialized trust via SecTrustSetExceptions(trust, exceptions) you suddenly end up with exceptions that were not there before and can change the evaluation result! (I've seen those suddenly appearing exceptions lead to an evaluation result of "proceed" instead of "recoverable trust failure").

Turn off FireFox driver refresh POST warning

I have inherited some GEB tests that are testing logging into a site (and various error cases/validation warnings).
The test runs through some validation failures and then it attempts to re-navigate to the same page (just to refresh the page/dom) and attempts a valid login. Using GEB's to() method, it detects that you are attempting to navigate to the page you are on, it just calls refresh - the problem here is that attempts to refresh the last POST request, and the driver displays the
"To display this page, Firefox must send information that will repeat any action (such as a search or order confirmation) that was performed earlier"
message - as the test is not expecting this popup, it hangs and the tests timeout.
Is there a way to turn off these warnings in Firefox webdriver? or to auto-ignore/accept them via Selenium or GEB?
GEB Version: 0.9.2,
Selenium Version: 2.39.0
(Also tried with minor version above: 0.9.3 & 2.40.0)
Caveats:
I know about the POST/Re-direct/GET pattern - but am not at liberty to change the application code in this case
The warning message only causes an issue intermittently (maybe 1 in 5 times) - I have put this down to speed/race conditions whereby the test completes the next actions before the message appears - I know a possible solution is to update tests to wait for message to appear and then accept, but my question is, is there a global setting that can just avoid these being triggered/displayed?
That refresh() is there to work around an issue with IE driver which ignores calls to driver.get() with the same url as the current one.
Instead of monkey patching Browser class (which might bite you somewhere down the line or might not) I would change the url of your login page class. You might for example add an insignificant query string - I think that simply a ? at the end should suffice. The driver.currentUrl == newUrl condition will evaluate to false and you will not see that popup anymore.
If I understand you issue properly this might help. In Groovy you can modify a class on the fly.
We use Spock with Geb and I placed this in a Super class which all Spock Spec inherit from. Eg: QSpec extends GebSpec.
It is the original method slightly modified with the original code commented out so you know what has been changed. I use this technique in several required places to alter Geb behaviour.
static {
Browser.metaClass.go = { Map params, String url ->
def newUrl = calculateUri(url, params)
// if (driver.currentUrl == newUrl) {
// driver.navigate().refresh()
// } else {
// driver.get(newUrl)
// }
driver.get(newUrl)
if (!page) {
page(Page)
}
}
}

Grails filter stops working after

I have a filter set up as follow to control users login status.
class SecurityFilters {
def filters = {
login(controller:'login|logout|proxy|API|error', action:'*', invert: true) {
before = {
if (!session.isLoggedIn){
switch(controllerName){
case "enroll":
switch(actionName){
...
default:
log.warn "Permission Denied. Default action for enroll."
render(view: '/permissionDenied', model: [message: "You must be logged in to access the enroll system. If you are a consumer, please contact your agent for more information."])
break
}
break
...
}
else {
switch(controllerName){
case "agent":
if (!session.user.isAgent) {
render view: "/permissionDenied", model: [message: 'This portion of the site is only available to agents.']
return false
}
break
....
}// switch
}// else
}// before
...
}// login
}// filters
The problem I am having is that when I run this in development it works fine but when I run it on our QA system it works fine for a while and then suddenly it stops working correctly.
I added logging and I can see that the session information is available in the filter and the session variable (session.user.isAgent) is set correctly (true) but the code inside the if(!session.user.isAgent) gets executed regardless.
I can's seem to find the cause for odd behaviour.
My question is has anyone seen this behaviour before and how did they solve it or have any ideas of where to look for probable cause for the sudden change in the way the filter is working.
Thanks in advance.
UPDATE (02/19/2014):
After adding more logging in an effort to hunt down the cause the filter did not execute the code in the if(!session.user.isAgent) as it was doing before. Now it runs normally and then executes only the render line for when the user is not logged in. The logging still show that the user is logged in and that (s)he is an agent but then it runs the render but not the lines of code above it. It is as if there was a "goto" the render line after it completes checking if the agent is logged in.
Again any information or solution would be appreciated
I've had a few issues with filters and Groovy truth. The problem I was seeing was that no errors were logged, even with aggressive exception catching (i.e. catching Throwable) and the only output in the browser was a blank page. This seems to happen only in Filters- everywhere else the errors get logged.
In my case, the issue was down to Groovy truth. I was trying to set a Boolean attribute on the session, but every time I did this it failed. In the end I had to convert the value to a String, and then set it, and it worked.
I know this isn't a direct answer, but I've been bitten a few times by the above and for example, lazy GString evaluation.
If you're still debugging, I'd log some output showing the underlying Class type of what you think you're dealing with. It may be that when your boolean conditions are evaluated above an exception is being thrown and swallowed. I'd log the actual values of each of your conditional statements to see what they are. Also remove each line one by one, to see if the failure goes away. And/or replace your conditionals with absolute values i.e. true/false to see if the code gets executed. If it does, it points to an error in the current conditional evaluation.

Meteor: unreliable session variable?

I'm making a service where there are no user accounts, and I want to restrict by what page I'm visiting.
So each page is a "box", and on each "box" I have a bunch of "files".
I've published the relevant info in server/publications.coffee
Meteor.publish 'files', (boxId)->
console.log boxId
return Files.find({boxId:boxId})
My file for 'box' has a subscription handle:
#filesHandle = Meteor.subscribe 'files', Session.get('currentBoxId')
And the currentBoxId is stored in the session variable.
Here's the crazy part: I expect this to work, and it does on the first time I start the server. The console.log in the first bit of code prints the proper ID. Then, all of a sudden the console log suddenly starts returning "null", even when I console.log the session var in the browser console, it returns correctly.
I feel like there's some kind of loading asynchrony issue here, but I have no idea what's going on.
Any clues?
Ah, figured it out. The template can be rendered before the session variable is set, apparently. Usually you put your collection handles in the main.js file in the application scope, but this doesn't work if the subscription depends on session variables.
I did the following:
Template.boxPage.created = ()->
#filesHandle = Meteor.subscribe 'files', Session.get('currentBoxId')

Meteor 0.5.9: replacement for using Session in a server method?

So, I was attempting to do something like the following:
if(Meteor.isServer){
Meteor.methods({connect_to_api: function(vars){
// get data from remote API
return data;
}});
}
if(Meteor.isClient){
Template.myTpl.content = function(){
Meteor.call('connect_to_api', vars, function(err,data){
Session.set('placeholder', data);
});
return Session.get('placeholder');
};
}
This seemed to be working fine, but, of course, now breaks in 0.5.9 as the Session object has been removed from the server. How in the world do you now create a reactive Template that uses a server-only (stuff we don't want loading on the client) method call and get data back from that Method call. You can't put any Session references in the callback function because it doesn't exist on the server, and I don't know of any other reactive data sources available for this scenario.
I'm pretty new to Meteor, so I'm really trying to pin down best-practices stuff that has the best chance of being future-proof. Apparently the above implementation was not it.
EDIT: To clarify, this is not a problem of when I'm returning from the Template function. This is a problem of Session existing on the server. The above code will generate the following error message on the server:
Exception while invoking method 'connect_to_api' ReferenceError: Session is not defined
at Meteor.methods.connect_to_api (path/to/file.js:#:#)
at _.extend.protocol_handlers.method.exception ... etc etc
Setting the session in the callback seems to work fine, see this project I created on github: https://github.com/jtblin/meteor_session_test. In this example, I return data in a server method, and set it in the session in the callback.
There are 2 issues with your code:
1) Missing closing brace placement in Meteor.methods. The code should be:
Meteor.methods({
connect_to_api: function(vars) {
// get data from remote API
return data;
}
});
2) As explained above, you return the value in the session, before the callback is completed, i.e. before the callback method had the time to set the session variable. I guess this is why you don't see any data in the session variable yet.
I feel like an idiot (not the first time, not the last). Thanks to jtblin for showing me that Session.set does indeed work in the callback, I went back and scoured my Meteor.method function. Turns out there was one spot buried in the code where I was using Session.get which was what was throwing the error. Once I passed that value in from the client rather than trying to get it in the method itself, all was right with the world.
Oh, and you can indeed order things as above without issue.

Resources