FW/1 App Calling onApplicationStart on Every Request - orm

I have a FW/1 app on Railo 4.2.2/Apache and for some reason it's calling onApplicationStart on every request. I can tell it's not any reinit code - put in a callStackGet() dump in setupApplication and can see that the root call is onApplicationStart (not via any init hook). Are there any known bugs in Railo that would cause this? I've double checked the application timeout (1 day) and the FW/1 setting - it's turned off - so there should be no reason the app would be losing application scope on every request.
There is another strange thing I'm seeing too, but I don't know that it is related. In setup application I am creating a new user object (via ORM) and persisting it if a local admin doesn't exist. I dump it and see the ID, but it's not in the database when I query the table (yes, I flushed it). The next page hit creates the user again (since it doesn't exist still...).
Edit: Add persist object code for Adam.
function setupApplication() {
// bean factory should look in the model tree for services and beans
var bf = new framework.ioc( "/com/sharp/model" );
setBeanFactory( bf );
ormReload();
if( getEnvironment() == 'dev' ){
writeLog('Checking for dev user');
if( !arrayLen( ormExecuteQuery('from User where username = ?', ['admin']) ) ){
var user = new com.sharp.model.user.User({username: 'admin', password: hash('p#ssw3rd'), isAdmin: true});
entitySave( user );
ormFlush();
writeDump(user);
writeDump(callStackGet());
writeLog('User admin created')
}
else{
var user = bf.getBean('userService').getByUsername('admin');
writeLog('Dev admin user already exists. Done.')
}
var auth = bf.getBean('userService').authenticate( 'admin', 'p#ssw3rd' );
}
}

I think the failure to persist to the DB may be a regression bug with Railo 4.2.2. See https://issues.jboss.org/browse/RAILO-3279
Try wrapping your save/flush in a transaction:
transaction{
entitySave( user );
ormFlush();
}
Normally you shouldn't need both. Either the transaction or ormFlush should make it persist.

Related

How do I force AWS Cognito to retrieve an IdentityId from the server?

In the iOS SDK (v2.4.8) I can't logout a user and then login as a different user correctly.
The (correct) cognityIdentityId returned by AWS for the first user (since an app start) is also returned for the second user (unless the app is restarted). This gives access to the AWSCognitoDataset of one user by another.
I think this is because the iOS SDK has cached the id and the documented call to clear that cache, doesn't fully work.
When logging in:
// one-off initialisation
self.credentialsProvider = AWSCognitoCredentialsProvider(regionType:AWSRegionType.USEast1, identityPoolId:Constants.CognitoIdentityPoolId)
let configuration = AWSServiceConfiguration(region:AWSRegionType.USEast1, credentialsProvider:self.credentialsProvider)
AWSServiceManager.defaultServiceManager().defaultServiceConfiguration = configuration
…
// I get idToken from my external provider serice (Auth0)
func doAmazonLogin(idToken: String, success : () -> (), _ failure : (NSError) -> ()) {
var task: AWSTask?
//Initialize clients for new idToken
if self.credentialsProvider?.identityProvider.identityProviderManager == nil || idToken != Application.sharedInstance.retrieveIdToken() {
let logins = [Constants.CognitoIDPUrl: idToken]
task = self.initializeClients(logins)
} else {
//Use existing clients
self.credentialsProvider?.invalidateCachedTemporaryCredentials()
task = self.credentialsProvider?.getIdentityId()
}
//Make login
task!.continueWithBlock { (task: AWSTask!) -> AnyObject! in
if (task.error != nil) {
failure(task.error!)
} else {
// the task result will contain the identity id
let cognitoId:String? = task.result as? String
self.customIdentityProviderManager!.addToken(Constants.CognitoIDPUrl, value:idToken)
//Store Cognito token in keychain
Application.sharedInstance.storeCognitoToken(cognitoId)
success()
}
return nil
}
}
func initializeClients(logins: [NSObject:AnyObject]?) -> AWSTask? {
//Create identity provider managet with logins
let manager = CustomIdentityProviderManager(tokens: logins!)
self.credentialsProvider?.setIdentityProviderManagerOnce(manager)
return self.credentialsProvider?.getIdentityId()
}
When logging out:
// Clear ALL saved values for this provider (identityId, credentials, logins). [docs][1]
let keychain = A0SimpleKeychain(service:"…")
keychain.clearAll()
I've also tried adding:
credentialsProvider!.clearCredentials()
credentialsProvider!.clearKeychain()
Is anyone using the AWS iOS SDK and has coded logout successfully such that a new user can login cleanly?
There is the oddly named method credentialsProvider.setIdentityProviderManagerOnce() - I can't find this documented but its name suggests that it should only be called once per session. But if keychain.clearAll() removes logins then one would need to call setIdentityProviderManagerOnce each time a new user logins in in order to setup logins each time.
Can you describe your login/logout flow a bit more? Cognito doesn't support multiple logins from the same provider per identity, so it sounds like, unless you're using multiple, it isn't actually changing the identity.
In any case, have you tried the clearKeyChain method on the credentials provider? It's largely for use cases like this - clearing everything.

Node.js client for wit.ai calls multiple custom actions

I'm trying to write an example app in wit.ai. I followed the quickstart app using node.js client that is shown at https://wit.ai/docs/quickstart.
The example shown there has only one custom action. But when I try to add a new story and a new action, I see that the context is being shared between the stories. This is causing wrong behaviour(a custom action from another story is being executed).
I cannot find any example with multiple custom actions and stories. Are there any node.js or python examples other than the ones from wit.ai websites?
You need to create a context for each session, and this is a quick example (from https://github.com/wit-ai/node-wit/blob/master/examples/messenger.js):
const findOrCreateSession = (fbid) => {
let sessionId;
// Let's see if we already have a session for the user fbid
Object.keys(sessions).forEach(k => {
if (sessions[k].fbid === fbid) {
// Yep, got it!
sessionId = k;
}
});
if (!sessionId) {
// No session found for user fbid, let's create a new one
sessionId = new Date().toISOString();
sessions[sessionId] = {
fbid: fbid,
context: { // New context per session id.
_fbid_: fbid
}
}; // set context, _fid_
}
return sessionId;
};
You can find a working example at https://github.com/hunkim/Wit-Facebook.
I suppose wit engine don't store context on their side.
You 'merge' function must merge entities in different ways, depending on your app logic.
But if you story is completed, you need to clear context for next stories.
I added a built-in function clear-context and call this function from wit as action.
Check out my example.
It's not an official api, but you can understand how wit http api works.

viaRemember not work - laravel

Auth :: attempt works perfect, but when you pass the second parameter "true" apparently does not care or does not recover with viaRemember
viaRemember fails to work, check this
controller User
`$`userdata = array(
'email' => trim(Input::get('username')),
'password' => trim(Input::get('password'))
);
if(Auth::attempt(`$`userdata, true)){
return Redirect::to('/dashboard');
}
view 'dashboard', always show 777
#if (Auth::viaRemember())
{{666}}
#else
{{777}}
#endif
I have hit the same obstacle, so looking into the code one can see that viaRemember is not meant to be used as a function to check if the user was logged into the system in one of all the ways a user can be logged in.
'viaRemember' is meant to check if a user was logged into the system specifically via the `viaRemember' cookie.
From what I gather, authentication of user is remembered in two ways:
a via remember cookie.
The cookie value is compared to the via remember field in the users table.
a session cookie.
The cookie value is used in the server to get the session from the
session store. On the session object from the store there is data attached. One of the
data items is the user id connected to the session. The first time
the session was created, the system attached the user id to the data
of the season.
In Illuminate\Auth\Guard class:
public function user()
{
if ($this->loggedOut) return;
// If we have already retrieved the user for the current request we can just
// return it back immediately. We do not want to pull the user data every
// request into the method because that would tremendously slow an app.
if ( ! is_null($this->user))
{
return $this->user;
}
$id = $this->session->get($this->getName());
// First we will try to load the user using the identifier in the session if
// one exists. Otherwise we will check for a "remember me" cookie in this
// request, and if one exists, attempt to retrieve the user using that.
$user = null;
if ( ! is_null($id))
{
$user = $this->provider->retrieveByID($id);
}
// If the user is null, but we decrypt a "recaller" cookie we can attempt to
// pull the user data on that cookie which serves as a remember cookie on
// the application. Once we have a user we can return it to the caller.
$recaller = $this->getRecaller();
if (is_null($user) && ! is_null($recaller))
{
$user = $this->getUserByRecaller($recaller);
}
return $this->user = $user;
}
The getUserByRecaller function is called only if the session cookie authentication did not work.
The viaRemember flag is only set in the getUserByRecaller function. The viaRemember method is only a simple getter method.
public function viaRemember()
{
return $this->viaRemember;
}
So in the end, we can use Auth::check() that does make all the checks including the viaRemember check. It calls the user() function in the Guard class.
It seems also the viaRemember is only an indicator. You need to do a type of Auth::check() the will get the process of authentication started and so the user() function will be called.
It seems that your project is on Laravel 4.0 but viaRemember() is added in Laravel 4.1! So that's expected.
in config\session.php file change the 'expire_on_close' = false to true and once you close restart your browser, it must be ok.

Meteor.loginWithPassword callback doesn't provide custom object in User accounts doc

Meteors loginWithPassword() function doesn't provide me the object systemData, which I adding to user doc (not to profile obj) during registration. The thing is, that if I look into console after logging in, I can see that object systemData (that means probably it's not publish issue), but not in callback of loginWithPassword() function, where I need them (to dynamically redirect user to proper page). Is there way to get this object, without any ugly things like timers?
Meteor.loginWithPassword(email, password, function(errorObject) {
if (errorObject) {
...
} else {
// returns true
if (Meteor.userId()) {
// returns false
if (Meteor.user().systemData) {
...
}
// user doc without systemData object
console.log(JSON.stringify(Meteor.user());
}
}
I've adding object systemData on creating user:
Accounts.onCreateUser(function(options, user) {
if (options.profile) {
user.profile = options.profile;
}
...
user.systemData = systemDataRegularUser;
return user;
});
Are you sure publish data to Client ?
I get User Info Using loginWithPassword in callback function.
Meteor.loginWithPassword username,password,(error,result1)->
options =
username: username
password: password
email: result['data']['email']
profile:
name: result['data']['display-name']
roles: result.roles
console.log Meteor.user(), result1
I Create user flowing code: (options contains systemData)
Accounts.createUser option
The first problem is that you want a custom field on a user document published to the client. This is a common question - see the answer here.
The next problem is that even after you add something like:
Meteor.publish("userData", function () {
return Meteor.users.find(this.userId, {fields: {systemData: 1}});
});
I think you still have a race condition. When you call loginWithPassword, the server will publish your user document, but it will also publish another version of the same document with the systemData field. You are hoping that both events have completed by the time Meteor.user() is called. In practice this may just work, but I'm not sure there is any guarantee that it always will. As you suggested, if you added a slight delay with a timer that would probably work but it's an ugly hack.
Alternatively, can you just add systemData to the user's profile so it will always be published?
I didn't find exact way how to solve this, but found easy workaround.
To make some action right after user logged in (eg. dynamically redirect user to proper page), you can hook on your home page with Iron router.(If you using it.) :
this.route('UsersListingHome', {
path: '/',
template: 'UsersListing',
data: function() { ... },
before: function() {
if (isCurrentUserAdmin() && Session.get('adminJustLogged') !== 'loggedIn') {
Router.go('/page-to-redirect');
Session.set('adminJustLogged','loggedIn');
}
}
});
After click on logout of course if (isCurrentUserAdmin()) { Session.set('adminJustLogged', null); }
I've further thought about calling Meteor.call('someMethod') to fetch userData object in Method callback, but now I'm satisfied.
PS: I know that it's not recommended to have plenty session variables or other reactive data source for speeding-up my app, but I believe, that one is not tragedy :)
PS2: Anyway, thanks for your answers.

How should I persist CredentialPickerResults.Credential for CredentialPickerOptions.PreviousCredential?

I am wanting to use a CredentialPicker to prompt for a username and password. When I configure an instance of this class, I can set CredentialPickerOptions.PreviousCredential to a value previously obtained by CredentialPickerResults.Credential. I believe this causes the dialog to prepopulate the credentials.
However, persisting this value appears to be non-trivial; it's an IBuffer, whose members don't appear to contain the relevant credentials. Programming Windows 8 Apps with HTML, CSS, and JavaScript, page 657, implies that this should be possible:
An IBuffer containing the credential as an opaque byte array. This is what you can
save in your own persistent state if needs be and passed back to the picker at a later time; we’ll
see how shortly.
Unfortunately, the we'll see how shortly appears to only refer to the fact that the value can be passed back from memory into PreviousCredential; I didn't find any mention of how it's persisted.
Also, I want to persist the credentials using the recommended approach, which I believe is to use PasswordVault, however, this appears to only allow me to save the credentials as username and password strings rather than an IBuffer.
Thanks for taking the time to ask, and I certainly agree that I could've been more clear in that part of the book. Admittedly, I spent less time on Chapter 14 than I would have liked, but I'll try to remedy that in the next edition. Feedback like yours is extremely valuable in knowing where I need to make improvements, so I appreciate it.
Anyway, writing a buffer to a file is something that was mentioned back in Chapter 8 (and could've been mentioned again here...page 325, though it doesn't mention IBuffer explicitly). It's a straightforward job using the Windows.Storage.FileIO class as shown below (promise!).
First, a clarification. You have two ways to save the entered credentials. If you want to save the plain-text credentials, then absolutely use the Credential Locker. The benefit here is that those credentials can roam automatically with the user if that roaming passwords is enabled in PC Settings (it is by default). Otherwise, you can save the opaque CredentialPickerResults.credential property directly to a file. It's already encrypted and scrambled, so you don't need to use the credential locker in that case.
Now for saving/loading the credential property, which is an IBuffer. For this you use FileIO.writeBufferAsync to save and FileIO.readBufferAsync to reload.
I modified the Credential Picker sample, scenario 3 to demonstrate this. To save the credential property, I added this code at the end of the completed handler for pickAsync:
//results.credential will be null if the user cancels
if (results.credential != null) {
//Having retrieved a credential, write the opaque buffer to a file
var option = Windows.Storage.CreationCollisionOption.replaceExisting;
Windows.Storage.ApplicationData.current.localFolder.createFileAsync("credbuffer.dat", option).then(function (file) {
return Windows.Storage.FileIO.writeBufferAsync(file, results.credential);
}).done(function () {
//No results for this operation
console.log("credbuffer.dat written.");
}, function (e) {
console.log("Could not create credbuffer.dat file.");
});
}
Then I created a new function to load that credential, if possible. This is called on the Launch button click instead of launchCredPicker:
//In the page ready method:
document.getElementById("button1").addEventListener("click", readPrevCredentialAndLaunch, false);
//Added
function readPrevCredentialAndLaunch() {
Windows.Storage.ApplicationData.current.localFolder.getFileAsync("credbuffer.dat").then(function (file) {
return Windows.Storage.FileIO.readBufferAsync(file);
}).done(function (buffer) {
console.log("Read from credbuffer.dat");
launchCredPicker(buffer);
}, function (e) {
console.log("Could not reopen credbuffer.dat; launching default");
launchCredPicker(null);
});
}
//Modified to take a buffer
function launchCredPicker(prevCredBuffer) {
try {
var options = new Windows.Security.Credentials.UI.CredentialPickerOptions();
//Other options omitted
if (prevCredBuffer != null) {
options.previousCredential = prevCredBuffer;
}
//...
That's it. I put the modified JS sample on http://www.kraigbrockschmidt.com/src/CredentialPickerJS_modified.zip.
.Kraig
Author, Programming Windows 8 Apps in HTML, CSS, and JavaScript (free ebook)