[rt-devel] showing people logged into RT (WebUI)

Bruce Campbell bruce_campbell at ripe.net
Fri Feb 15 08:43:45 EST 2002


On Thu, 14 Feb 2002, RT2 Troubles wrote:

> - Making a list of who is logged into the RT web pages and perhaps how long
> they have been idle. This would be really handy when collaborating with
> multiple people on a specific task. I could also use it to tell me when it's
> safe to restart the server.
> * It has already been suggested that this could easilly be done by creating
> or touching a file in an "online" directory that has the same name as the
> current use. This file would be created/touched each time any action is done
> in RT with the exception of auto-refresh actions. A cron script could remove
> stale user files to prevent problems created by people who just remain idle
> or simply close the browser without logging out. The final step would be
> setting up a script in RT that shows the user names in the dir and uses the
> date of the files to display an 'idle' value.

Hrm.  Using a seperate file sounds painful actually, as you're depending
on external scripts to cleanup.  Use the Force Luke, or in this case,
the appropriately named Watchers table.

	id Type Scope Value Email Quiet Owner Creator Created
	LastUpdatedBy LastUpdated.

Watcher.pm mentions that the only Scopes in use are 'Ticket' and 'Queue'.
Ergo, using a Scope of 'WebUI' would not conflict with anything, and a
check of code applying limits to Watcher objects bears this out.

Next, we have the problem of how to update this table.  As pretty much
everything includes (WebRT/html)/Elements/Header, having this file include
(patch-Header) something else (UpdateWho) to update the table is pretty
easy

Note that lib/RT/Watcher.pm needs to be patched to allow a Type of
'Viewer', otherwise we can't create our Watcher (patch-Watcher).

Once we've done that, the only thing remaining is to retrieve the
information in a nice fashion, and make it visible (ShowWho).  In my setup
I've added it to WebRT/html/Elements/Tabs (patch-Tabs).

Finally, we want to know when people logout, so we patch
WebRT/html/NoAuth/Logout.html (patch-Logout) to call UpdateWho with a -1
value.

There is a future thing in UpdateWho which will give the ability to force
a log out of WebUI users, but something which does that has not been
implemented.

Use at your own risk, as always ;)

Regards,


-- 
                             Bruce Campbell                            RIPE
                   Systems/Network Engineer                             NCC
                 www.ripe.net - PGP562C8B1B                      Operations
-------------- next part --------------
<%PERL>
# We're wanting to show who is logged in.
# We rely heavily on the caching inherent in DBIx::SearchBuilder and friends
# to avoid overloading our SQL server.

# If we have a CurrentUser defined:
if ($session{'CurrentUser'}){

	# Get our watcher for this session.
	my $watchers = RT::Watchers->new( $RT::SystemUser );

	# The Owner should be the current user.  Use an existing Watcher
	# object if possible.
	$watchers->Limit( FIELD => 'Scope',
			  VALUE => 'WebUI' );
	$watchers->Limit( FIELD => 'Type',
			  VALUE => 'Viewer' );
	# Anyone not marked as 'logged out'.
	$watchers->Limit( FIELD => 'Value',
			  VALUE => -1,
			  OPERATOR => '!=' );
	$watchers->OrderBy( FIELD => 'LastUpdated',
			    ORDER => 'DESC' );
</%PERL>

	<form action="/">
	Current People Active: (<% $watchers->Count() %>)
        <select NAME="not used">
% while( my $watcher = $watchers->Next() ){
        <option VALUE="<% $watcher->id %>">
		<% $watcher->OwnerObj->RealName %>
		<% $watcher->LastUpdatedObj->ISO %>
	</option>
% }
	</select>
	</form>

% }
-------------- next part --------------
<%ARGS>
$setval => undef
</%ARGS>
<%PERL>
# We're wanting to update the Watchers table 
# We rely heavily on the caching inherent in DBIx::SearchBuilder and friends
# to avoid overloading our SQL server.

# If we have a CurrentUser defined:
if ($session{'CurrentUser'}){

	# Get our watcher for this session.
	my $watchers = RT::Watchers->new( $RT::SystemUser );

	# The Owner should be the current user.  Use an existing Watcher
	# object if possible.
	$watchers->Limit( FIELD => 'Owner', 
			  VALUE => $session{'CurrentUser'}->Id );
	$watchers->Limit( FIELD => 'Scope',
			  VALUE => 'WebUI' );
	$watchers->Limit( FIELD => 'Type',
			  VALUE => 'Viewer' );

	my $watcher = $watchers->Next();

	unless( $watcher ){
		# We don't have a watcher?  Must be the first time they
		# logged in.
		$watcher = RT::Watcher->new( $RT::SystemUser );

		my ($retval, $msg) = $watcher->Create(Scope => 'WebUI', 
                                      Type => 'Viewer',
                                      Owner => $session{'CurrentUser'}->Id,
				      Value => 0
                           );
		# print "<!-- UpdateWho $msg -->\n";
	}

	# Did we get passed something?
	# Intended to be used by Logout.
	if( defined( $setval ) ){
		$watcher->SetValue( $setval );
	}

	# Did we get logged out by an admin?
	if( ! defined( $watcher->Value ) ){
		# Someone set our value to NULL.  This indicates that
		# we have been logged out by an admin.  Include the
		# normal Logout.html which also calls abort().
		# Set the value to -1 *first* to avoid problems next time
		$watcher->SetValue( -1 );
</%PERL>
<& /NoAuth/Logout.html &>
<%PERL>
	}

	# We have a watcher.  Get the current time.
	my $now = RT::Date->new( $RT::Nobody );
	$now->SetToNow();

	# If we've been updated in the last minute, don't stress the
	# widdle SQL server.
	if( $now->Diff( $watcher->LastUpdatedObj ) > 60 ){
		# Update it.

		# We'll use a number here for indicating 'logged in'.
		# We could indicate the ticket here as well.
		$watcher->SetValue( $watcher->Value + 1 );

	}		

}else{

	print "<!-- UpdateWho noUser found (no session?) -->\n";
}
</%PERL>
<!-- UpdateWho included -->
-------------- next part --------------
51a52
> <& /Elements/UpdateWho &>
-------------- next part --------------
117c117
<       unless ($args{'Type'} =~ /^(Requestor|Cc|AdminCc)$/i);
---
>       unless ($args{'Type'} =~ /^(Requestor|Cc|AdminCc|Viewer)$/i);
193c193
< 	($args{'Type'} !~ /^(Requestor|Cc|AdminCc)$/i)) {
---
> 	($args{'Type'} !~ /^(Requestor|Cc|AdminCc|Viewer)$/i)) {
-------------- next part --------------
120c120
< 	A => { html => $m->scomp('/Elements/CreateTicket')	
---
> 	A => { html => $m->scomp('/Elements/ShowWho')	
122c122,124
< 	B => { html => $m->scomp('/Elements/GotoTicket') 
---
> 	B => { html => $m->scomp('/Elements/CreateTicket')	
> 		},
> 	C => { html => $m->scomp('/Elements/GotoTicket') 
-------------- next part --------------
8a9
> <& /Elements/UpdateWho, setval => -1 &>


More information about the Rt-devel mailing list