Commit a896be22 authored by Leigh Stoller's avatar Leigh Stoller

Add support for user session tracking and Google Analytics.

If we assign a unique constant random value to every user, and spit that
out in the initial ga() stuff at the beginning of each page load, google
can combine interactions from the same user across different devices.
Say, like work vs home computer.
parent e7147d5d
...@@ -225,6 +225,7 @@ sub nonlocal_type($) { return field($_[0], "nonlocal_type"); } ...@@ -225,6 +225,7 @@ sub nonlocal_type($) { return field($_[0], "nonlocal_type"); }
sub IsLocal($) { return (defined($_[0]->nonlocal_id()) ? 0 : 1); }; sub IsLocal($) { return (defined($_[0]->nonlocal_id()) ? 0 : 1); };
sub IsNonLocal($) { return (defined($_[0]->nonlocal_id()) ? 1 : 0); }; sub IsNonLocal($) { return (defined($_[0]->nonlocal_id()) ? 1 : 0); };
sub portal($) { return field($_[0], "portal"); } sub portal($) { return field($_[0], "portal"); }
sub ga_userid($) { return field($_[0], "ga_userid"); }
sub Brand($) { return $_[0]->{'BRAND'}; } sub Brand($) { return $_[0]->{'BRAND'}; }
sub isAPT($) { return $_[0]->Brand()->isAPT() ? 1 : 0; } sub isAPT($) { return $_[0]->Brand()->isAPT() ? 1 : 0; }
sub isCloud($) { return $_[0]->Brand()->isCloud() ? 1 : 0; } sub isCloud($) { return $_[0]->Brand()->isCloud() ? 1 : 0; }
...@@ -614,6 +615,9 @@ sub Create($$$$) ...@@ -614,6 +615,9 @@ sub Create($$$$)
# And a verification key. # And a verification key.
my $verify_key = TBGenSecretKey(); my $verify_key = TBGenSecretKey();
# Google Analytics user id.
my $ga_userid = substr(TBGenSecretKey(), 0, 32);
if (! $nouuid) { if (! $nouuid) {
# And a UUID (universally unique identifier). # And a UUID (universally unique identifier).
$uuid = NewUUID(); $uuid = NewUUID();
...@@ -637,6 +641,7 @@ sub Create($$$$) ...@@ -637,6 +641,7 @@ sub Create($$$$)
push(@insert_data, "verify_key='$verify_key'"); push(@insert_data, "verify_key='$verify_key'");
push(@insert_data, "uid_idx='$uid_idx'"); push(@insert_data, "uid_idx='$uid_idx'");
push(@insert_data, "uid='$uid'"); push(@insert_data, "uid='$uid'");
push(@insert_data, "ga_userid='$ga_userid'");
if ($archived) { if ($archived) {
# #
......
...@@ -5156,6 +5156,7 @@ CREATE TABLE `users` ( ...@@ -5156,6 +5156,7 @@ CREATE TABLE `users` (
`initial_passphrase` varchar(128) default NULL, `initial_passphrase` varchar(128) default NULL,
`genesis` enum('emulab','aptlab','cloudlab','phantomnet') NOT NULL default 'emulab', `genesis` enum('emulab','aptlab','cloudlab','phantomnet') NOT NULL default 'emulab',
`portal` enum('emulab','aptlab','cloudlab','phantomnet') default NULL, `portal` enum('emulab','aptlab','cloudlab','phantomnet') default NULL,
`ga_userid` varchar(32) default NULL,
PRIMARY KEY (`uid_idx`), PRIMARY KEY (`uid_idx`),
KEY `unix_uid` (`unix_uid`), KEY `unix_uid` (`unix_uid`),
KEY `status` (`status`), KEY `status` (`status`),
......
use strict;
use libdb;
sub DoUpdate($$$)
{
my ($dbhandle, $dbname, $version) = @_;
if (!DBSlotExists("users", "ga_userid")) {
DBQueryFatal("alter table users add " .
" `ga_userid` varchar(32) default NULL after portal");
}
return 0;
}
# Local Variables:
# mode:perl
# End:
...@@ -99,6 +99,7 @@ $PAGEHEADER_FUNCTION = function($thinheader = 0, $ignore1 = NULL, ...@@ -99,6 +99,7 @@ $PAGEHEADER_FUNCTION = function($thinheader = 0, $ignore1 = NULL,
if (($login_user = CheckLogin($status)) != null) { if (($login_user = CheckLogin($status)) != null) {
$login_status = $status; $login_status = $status;
$login_uid = $login_user->uid(); $login_uid = $login_user->uid();
$ga_userid = $login_user->ga_userid();
} }
if ($login_user && !($login_status & CHECKLOGIN_WEBONLY)) { if ($login_user && !($login_status & CHECKLOGIN_WEBONLY)) {
$showmenus = 1; $showmenus = 1;
...@@ -140,10 +141,14 @@ $PAGEHEADER_FUNCTION = function($thinheader = 0, $ignore1 = NULL, ...@@ -140,10 +141,14 @@ $PAGEHEADER_FUNCTION = function($thinheader = 0, $ignore1 = NULL,
if ($TBMAINSITE && !$embedded && file_exists("../google-analytics.php")) { if ($TBMAINSITE && !$embedded && file_exists("../google-analytics.php")) {
readfile("../google-analytics.php"); readfile("../google-analytics.php");
echo "<script type='text/javascript'> echo "<script type='text/javascript'>\n";
ga('create', '$GOOGLEUA', 'auto'); echo " ga('create', '$GOOGLEUA', 'auto');\n";
ga('send', 'pageview'); if ($login_user) {
</script>"; echo " ga('set', 'userId', '$ga_userid');\n";
}
echo " ga('send', 'pageview');\n";
echo " window.GOOGLEUA = '$GOOGLEUA';\n";
echo "</script>";
} }
echo " echo "
......
<?php <?php
# #
# Copyright (c) 2000-2016 University of Utah and the Flux Group. # Copyright (c) 2000-2017 University of Utah and the Flux Group.
# #
# {{{EMULAB-LICENSE # {{{EMULAB-LICENSE
# #
...@@ -419,7 +419,12 @@ function LoginStatus() { ...@@ -419,7 +419,12 @@ function LoginStatus() {
$CHECKLOGIN_STATUS = CHECKLOGIN_NOTLOGGEDIN; $CHECKLOGIN_STATUS = CHECKLOGIN_NOTLOGGEDIN;
return $CHECKLOGIN_STATUS; return $CHECKLOGIN_STATUS;
} }
$ga_userid = $CHECKLOGIN_USER->ga_userid();
if (!$ga_userid) {
$ga_userid = substr(GENHASH(), 0, 32);
$CHECKLOGIN_USER->SetGaUserid($ga_userid);
}
# #
# Now add in the modifiers. # Now add in the modifiers.
# #
...@@ -884,6 +889,7 @@ function DOLOGIN($token, $password, $adminmode = 0, $nopassword = 0) { ...@@ -884,6 +889,7 @@ function DOLOGIN($token, $password, $adminmode = 0, $nopassword = 0) {
$usr_name = $user->name(); $usr_name = $user->name();
$uid_idx = $user->uid_idx(); $uid_idx = $user->uid_idx();
$usr_email = $user->email(); $usr_email = $user->email();
$ga_userid = $user->ga_userid();
# Check for frozen accounts. We do not update the IP record when # Check for frozen accounts. We do not update the IP record when
# an account is frozen. # an account is frozen.
...@@ -918,6 +924,10 @@ function DOLOGIN($token, $password, $adminmode = 0, $nopassword = 0) { ...@@ -918,6 +924,10 @@ function DOLOGIN($token, $password, $adminmode = 0, $nopassword = 0) {
# #
# Pass! # Pass!
# #
if (!$ga_userid) {
$ga_userid = substr(GENHASH(), 0, 32);
$user->SetGaUserid($ga_userid);
}
# But inactive users need special handling. # But inactive users need special handling.
if ($user->status() == TBDB_USERSTATUS_INACTIVE) { if ($user->status() == TBDB_USERSTATUS_INACTIVE) {
......
<?php <?php
# #
# Copyright (c) 2006-2016 University of Utah and the Flux Group. # Copyright (c) 2006-2017 University of Utah and the Flux Group.
# #
# {{{EMULAB-LICENSE # {{{EMULAB-LICENSE
# #
...@@ -347,6 +347,7 @@ class User ...@@ -347,6 +347,7 @@ class User
function mailman_password() { return $this->field("mailman_password"); } function mailman_password() { return $this->field("mailman_password"); }
function nonlocal_id() { return $this->field("nonlocal_id"); } function nonlocal_id() { return $this->field("nonlocal_id"); }
function portal() { return $this->field("portal"); } function portal() { return $this->field("portal"); }
function ga_userid() { return $this->field("ga_userid"); }
function isAPT() { return ($this->portal() && function isAPT() { return ($this->portal() &&
$this->portal() == "aptlab" ? 1 : 0); } $this->portal() == "aptlab" ? 1 : 0); }
function isCloud() { return ($this->portal() && function isCloud() { return ($this->portal() &&
...@@ -1199,6 +1200,14 @@ class User ...@@ -1199,6 +1200,14 @@ class User
return mysql_num_rows($query_result); return mysql_num_rows($query_result);
} }
function SetGaUserid($id) {
$idx = $this->uid_idx();
DBQueryFatal("update users set ga_userid='$id' ".
"where uid_idx='$idx'");
$this->user["ga_userid"] = $id;
return 0;
}
# #
# Return project access list for a user. This returns just pid,eid for # Return project access list for a user. This returns just pid,eid for
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment