How to deal with authenticated state in a SproutCore application - sproutcore

In a (now sort of deleted) question by Peter Kniestedt he was wondering where and how to set a timer to check for the authentication of the user.
His question is part of a larger question (which is the title of this question). Because I think it is important that this question is answered, I created a new question as a way to gather all the important information in one spot.

This is a typical case for the use of statechart, and more specifically concurrent states.
If you didn't know already, SproutCore contains a very useful library called SC.Statechart, which is a way of dealing with application state in a way which is much more controllable than through the use of boolean properties, as it also acts like a responder as well as a controller.
In this case you'd want a statechart which in the root has two concurrent states: one to deal with the states around authentication, and one to deal with the rest of the application.
MyApp.statechart = SC.Statechart.create({
rootState: SC.State.design({
substatesAreConcurrent: true,
AUTH: SC.State.design({
initialSubstate: 'CHECKAUTH',
CHECKAUTH: SC.State.design({
}),
LOGIN: SC.State.design({
}),
AUTHENTICATING: SC.State.design({
}),
AUTHENTICATED: SC.State.design({
}),
}),
APPMAIN: SC.State.design({
})
})
});
How is this supposed to work:
When your app starts, it will go to two states at once, one being the APPMAIN state which is the state which deals with the application itself. The other is the AUTH state, which will immediately go to the initial substate CHECKAUTH, which checks whether the user has a valid session. If not, this state should go to the LOGIN state, which is responsible for showing a login screen. When the user then performs a login, the LOGIN state transitions to the AUTHENTICATING state, which does the server checking. If this the attempt is invalid or incorrect, the AUTHENTICATING state should transition to LOGIN, otherwise to AUTHENTICATED.
To answer the original question this question is based on: if you need a timer somewhere which regularly checks whether the authentication is still valid, it should be in the AUTHENTICATED state. If it would fail, you can immediately transition to the LOGIN state, to display the login screen.
Using the state chart like this prevents the user having to reload or quit the application in order to login again, and possibly lose data as a result. In short it makes a much better user experience.

Related

How does pessimistic locking work across requests in Rails?

If a user is editing a resource with pessimistic lock no one else can edit the resource until the editing user saves his changes. Now to my question, what happens when the editing user did not save his changes but clicks on the browser back button to get to the last view? Is the resource still locked or is the lock dismissed? The same question applies to the scenario where the editing user is on the editing view and then navigates to another view over the links in a navigation bar. Does the user needs to come back to the edit view of the specific resource and save the changes before the lock is dismissed? And if yes, how can the lock be dismissed when the edit view is exited through other buttons than the save button?
The usual implementation of pessimistic locks in Rails, i.e. the use of ActiveRecord::Locking::Pessimistic obtains a lock on data during a database transaction. Thus, the lock is obtained and released during a single web request and does not spawn over multiple requests (such as a wizard or a multi-step process in your app). This can be useful to ensure that concurrent requests updating the same resources do not produce inconsistent data.
If you need a lock to be held over multiple requests, you need to implement this in some other way which is not dependent on an open database transaction.
To answer your question specifically: the pessimistic lock is not held while the user edits data in their browser. It is obtained when the user sends their changes to the server and released after. Thus, locking is unaffected if the user clicks the back button or doesn't send any changes because the lock is not held at that point.

Is there any way to bring an ASP.NET MVC application into "single user mode", rejecting new logins?

Is there a strategy/approach that can be built to bring an ASP.NET MVC application into "single user mode" gracefully? By "single user mode" I mean something that when activated will block all new user access/logins, but allow existing users to complete their sessions and log out.
SCENARIO: I need to republish an active MVC application during the day in order to patch errors. Since we are conducting a new release I need to be able to do these patches sometimes a few times a day to squash bugs. Our users are all over the world and I don't have the ability to contact them individually to tell them of the patch, especially if it is a quick fix that is needed. So far I've just been republishing which means for some users their sessions will be destroyed, they will get errors when trying to navigate from one screen or form to another, etc.
What I would like is a feature that will let me log in as the site admin (custom Identity auth), flip a switch, and from that point forward (unless I flip the switch again) no new logins will be accepted. I would also need the ability to monitor sessions and ideally mark individual sessions for termination immediately if necessary, which I'm not sure is possible out of the box at all.
If there is no NuGet package or at least some code sample out there that can do it I'm considering rolling my own. One approach is giving the app admin a screen to set a boolean Application variable that is then checked during each user's login. If that Application variable is true then the authentication logic redirects the user to a friendly message that logins are disabled. Session management would be trickier, maybe have the base controller update an Application variable (dictionary?) on each page load, and then the admin can view a screen that shows a list of those sessions and can flag them for termination? And then the next time a flagged user loads a screen the base controller logs them out since they were flagged for termination. But I'm not sure if there will be threading/deadlock/etc issues with everyone accessing this Application variable repeatedly like that.
For reference, the application is used by about 3-5K different users per day, about 25-30k screen/page views per day. Backend is a combination of Oracle and SQL Server but that shouldn't matter, unless it would be better to track the session info in the DB.
This is not a hard requirement, but the impact on the users when the site goes down can be severe, so I want to make it as graceful as possible. Right now it is crude.

Store User Token, If Invalid token - present Login page,

Learning iOS Swift programming and like to know how to implement user login process ?
The backend-iOS mechanism is this :
User login with email and Password,
The Server returns user token and user id
In subsequent requests, user token and user id is sent to fetch data/work with the App.
I have doubt in iOS implementation.
Will be storing User token and User id in Core Data. Will there be
any slowness if I get the user token on every screen from Core
Data?
If the login token expires or is invalid on any screen, how to fall back to login page? Should I check the JSON output and have code "present login VC" on every screen? Any streamlined way to have abstract the code to a swift or cocoa touch file?
Actually, there are many approaches. It's all depends on you, how you will manage it. I can point you two examples, how I manage it by myself.
Using NSOperation.
There was an awesome session on WWDC 2015, about advanced NSOperations. Here it is.
Basically, you create a subclass of NSOperaton and make other operations depend on it. In your case, you will have operation of user login, and all other operations will depend on user login (of course only ones, who needs it). If it succeed, then operation will execute. In user login operation, you will check, if user already logged in, and you have a token, if not, present logging screen.
There is also awesome library called Operations, based on that WWDC talk. Here it is.
Using PromiseKit.
Here is another one, using PromiseKit. It is not really much difference from operations, but, in my opinion, a little simpler. You create Promise that ensures that you did login. It is very simple to make a chain of promises, so you promise a user login and chain anything else from it. If login succeed, chain of promises continues executing.
It's all based on another awesome library, PromiseKit. Here it is
It is very powerful and very simple to use, once you understand the thing. It is very well documented, and has a bunch of tutorials here.
There are many other approaches, so you can choose any of it, and combine one with other however you like.
Asking on your first question, you make it asynchronous, so it is not so much matter about slowness of CoreData as you make a web request.
1 - well, yes, a bit. But I doubt you will notice any lag or anything: CoreData is really fast and it won't take any significant amount of time to fetch just one object. Alternatively, your CoreData object that holds this data (let's call it User) can be a property of your subclass of UIApplicationDelegate (let's call it MyAppDelegate). You will fetch this User in
- application:didFinishLaunchingWithOptions:, and update it on login/logout/expire/etc. In such way you can access it from everywhere, and you don't need to fetch it from CoreData anytime you need it.
Also, instead of CoreData you can use iOS Keychain. (Here is tutorial that might help with this).
2 - again, you can use MyAppDelegate. For example you can add method to it, that will save current navigation state, and change root controller of UIWindow to your LoginViewController. Or it will present LoginViewController on top of current controller. After successful login you will return navigation stack to previous state.
Also you can move this code to some kind of NavigationController - class that will handle this situation. It will have something like
func checkToken(Dictionary response, UIViewController currentController) -> Bool. If token is valid, it just returns true, and if not, it returns false and handles navigation to LoginViewController, and after login - back to currentController. This NavigationController can be property of MyAppDelegate, it can be singleton, created every time you need it, or you can pass it along to every UIViewController that you show.

Detecting moment of user session timeout and executing a method

I have a need to make a change to a database value at the moment that a user logs out. I can make this happen when the user clicks 'logout', but I need this to happen when a user times out as well. Is there some sort of listener or other such method I can use to achieve this?
Basically, due to SimpleMembership not supporting online user checking, I am forced to use a database field, a boolean, that records if a user has clicked login or logout, but obviously I cannot set this field to "false" if unless they click logout. Hence my need to detect automatic logouts, so to speak.
Any suggestions?
See: How to get notified of session end?
If you're sessions are in-process you can subscribe to the Session_End event. You will eventually (after the session timeout has expired) be notified that the session has ended.
ASP.NET has session states. So the one you should be interested is the Session_OnEnd event. But you can only use this inProc mode.
Refer to: http://msdn.microsoft.com/en-us/library/ms178583.aspx
Add this to Global.asax
public void Session_OnEnd()
{
//Perform your logic.
}
You will not be able to subscribe to any notification that lets you know when the session times out.
Instead, you will need to keep track (most likely in a database) of when the user performed their last action. Then have some sort of job that will periodically check to see those members that have not performed an action in any given time-frame and trigger the logout method.

Prevent session refresh by ajax call (grails)

I have a Grails based web app which uses Spring Security to handle user logins etc. I have hit a bit of a block and am hoping the more experienced might be able to point me in the right direction for a solution.
The application has the concept of messages which can be sent from user to user to provide a instant messaging feature. There is a timed Ajax call that is present throughout the system which is used to alert the user of any new incoming messages.
My problem is that since I have implemented this, each time the ajax call is performed, of course the users session is being refreshed, therefore never timesout. So a manual 'log out' is the only way they can log out, whereas before expiry of a session would redirect them to the login page.
Does anyone know how I can still accomplish automatic logouts whilst still have the timer functioning?
I'm hoping I can set up some kind of filter with spring security, or perhaps there's an annotation I can use on the periodically called method to instruct it NOT to refresh the users session.
As always any help & comments are appreciated.
Thanks to Long for pointing me in a different direction with his comment, I believe I have now a much better, more intuitive user friendly solution.
Rather than trying to change things on the backend, I am using a little jQuery script which is very easily configured and fits in perfect with my app which already uses jQuery and the jQuery UI.
After a specific period, a jQuery dialog pops up, modally dimming the background and informs the user due to inactivity they will soon be logged out. A progress bar is displayed which reduces until it is empty at which point if the user hasn't click my 'Continue Working' button, then I change the window location to the spring security logout controller URL, taking them back to the sign in page. It works beautifully and is very easy to configure.
The instructions can be found here : http://kenbrowning.blogspot.co.uk/2010/04/are-you-still-there.html
Kudos to Ken Browning for his library.

Resources