StrataFrame Forum

How to tell which users are currently logged?

http://forum.strataframe.net/Topic26111.aspx

By Edhy Rijo - 2/18/2010

Hi,



I need to show in a report or form which users defined in RBS are currently logged into the application, is there a property or method of SFSUsersBO that can help me get that information?



I was playing with SecurityBasics.CurrentUser.LoggedOnAt but don't know if this field is set to null or something after the user log out.
By Greg McGuffey - 2/18/2010

A user being logged in is strictly a client thing. I.e. the application knows, via the CurrentUser, who current user is, but this isn't "live". Essentially what happens is that when you log in, the class is loaded with the data needed to determine access via the RBS. Nothing is stored anywhere related to this.



Yes, this has come up before for me. Blink However, this architecture allows for some extensions to RBS that I've had to implement, specifically, dynamically setting the permissions (roles actually) of a user based on runtime parameters (which consulting project they will be working on). Thus, on one project they can edit data and on another they can only read data and on a third they can edit and configure the project as a manager. This works because I can set roles right before SF setups the current user and it won't affect any other sessions they are logged into.



Back to determining who's using the app. I've had a couple of thoughts on how to deal with this:



1. Use the auditing class to update the auditing database when a user logs in or out (Security.Auditor.InsertAuditEvent method). Then you could query this to determine who is logged in. However, if the app crashes, it might orphan users because they wouldn't be noted as having logged out.



2. Use a fancy, mancy app server (like the one to track licenses), and have the client periodically send an update that they are online. This would be very similar to how a chat program works, though it would be your client app chatting with an app server. The app server could then be queried to determine who all is currently online. This could then handle crashes, by marking users as questionable after a certain time of not hearing from them and as logged off after a bit more time.



Hope that helps!
By Edhy Rijo - 2/18/2010

Hi Greg, thanks for jumping in Smile.



I went a 3rd route and did the following keeping in mind future enhancements or needs:

1- Create a new table using the Computer Name as the PK, in my case the application can only be open once per workstation, so I also wanted to know in which computer was this user logged, I have other fields like the UserLogged, UserPK DisplayName and LoggedOnAt which are self explanatory.



2- In the new table's BO I added a method that will set the UserLogged True/False for the current Workstation Name (Environment.MachnineName), here is the code, pretty basic Cool



'''

''' Set the UserLogged True/False for the current workstation.

'''


''' True when the user is currently logged, False otherwise.

''' Called from the frmMainForm.vb

Public Sub SetCurrentUserLoggedStatus(ByVal LoggedStatus As Boolean)

Me.FillByPrimaryKey(Environment.MachineName)

If Me.Count = 0 Then

Me.NewRow()

End If



If Me.Count > 0 Then

Dim currentUserDisplayName As String = String.Empty

If SecurityBasics.CurrentUser.UserName.Equals("Administrator", StringComparison.CurrentCultureIgnoreCase) Then

currentUserDisplayName = SecurityBasics.CurrentUser.UserName

Else

currentUserDisplayName = MicroFour.StrataFrame.Security.BusinessObjects.SFSUsersBO.RetrieveDisplayName(SecurityBasics.CurrentUser.UserPK)

End If



Me.UserLogged = LoggedStatus

Me.LoggedOnAt = Now

Me.LoggedUserDisplayName = currentUserDisplayName

Me.Save()

End If

End Sub





3- I have a MainForm which is always open, so I added 2 events handles to detect when a user has logged and when the form is closing to call my code above.



AddHandler MicroFour.StrataFrame.Security.SecurityBasics.CurrentUserChanged, AddressOf UpdateCurrentUserInfo

AddHandler Me.FormClosed, AddressOf HandleFormClosed



Of course in the delegate methods above you need to call SetCurrentUserLoggedStatus(True/False) to do the trick.



This was a very quick code, so if I am missing something or you guys see where to enhance it, please let us know. Hehe
By Greg McGuffey - 2/19/2010

Nice. That is pretty much what my method 1 did, except is was using the SF Auditor class and associated table. I was going to keep a history of the login/logouts to see what usage was. Because you're not doing that, you code is simpler BigGrin
By Dustin Taylor - 2/22/2010

Very nice indeed!  For what it is worth, we use Greg's second mothod in our medical app. We have a central server service that handles licensing and such, and the clients send it login, shutdown, and keepalive updates.  The administrator can then go and view all open applications, who is logged in to them, and can kill any particular session if desired.  Works well, but your way is much simpler Smile.
By Greg McGuffey - 2/22/2010

For what it is worth, we use Greg's second method in our medical app.




Hmmm...wonder where I got the idea from.... Wink
By Edhy Rijo - 2/22/2010

Dustin Taylor (02/22/2010)
Very nice indeed!




Thanks Dustin!



I have 70% done for the server service, it is just that I have not have the time to finish it and fully test it. But in reality the administrator is not always at the server location, so been able to log into any workstation and see who is logged is really useful, at lest for me Tongue



My plan is to have the server service in the same fashion as you have, of course Trent gave us the idea a year or so ago, but being new to .NET/ VB and MS-SQL there was too much to absorb. My quickest solution is not perfect but can be enhanced and probably incorporate it in the same fashion of the RBS in which a system table will be used by default.