Commit fd925e89 by Julia Hansbrough

Add server-side analytics logging for login

Also, removed the client-side analytics for logging in.
Ensures that analytics are collected for third-party-auth logins.
Fixed failing tests related to third-party-auth.
parent 9a1687ab
......@@ -46,7 +46,8 @@ from student.models import (
Registration, UserProfile, PendingNameChange,
PendingEmailChange, CourseEnrollment, unique_id_for_user,
CourseEnrollmentAllowed, UserStanding, LoginFailures,
create_comments_service_user, PasswordHistory, UserSignupSource
create_comments_service_user, PasswordHistory, UserSignupSource,
anonymous_id_for_user
)
from student.forms import PasswordResetFormNoActive
......@@ -91,6 +92,9 @@ from util.password_policy_validators import (
from third_party_auth import pipeline, provider
from xmodule.error_module import ErrorDescriptor
import analytics
from eventtracking import tracker
log = logging.getLogger("edx.student")
AUDIT_LOG = logging.getLogger("audit")
......@@ -380,6 +384,10 @@ def register_user(request, extra_context=None):
'username': '',
}
# We save this so, later on, we can determine what course motivated a user's signup
# if they actually complete the registration process
request.session['registration_course_id'] = context['course_id']
if extra_context is not None:
context.update(extra_context)
......@@ -936,6 +944,31 @@ def login_user(request, error=""): # pylint: disable-msg=too-many-statements,un
if LoginFailures.is_feature_enabled():
LoginFailures.clear_lockout_counter(user)
# Track the user's sign in
if settings.FEATURES.get('SEGMENT_IO_LMS') and hasattr(settings, 'SEGMENT_IO_LMS_KEY'):
tracking_context = tracker.get_tracker().resolve_context()
analytics.identify(anonymous_id_for_user(user, None), {
'email': email,
'username': username,
})
# If the user entered the flow via a specific course page, we track that
registration_course_id = request.session.get('registration_course_id')
analytics.track(
user.id,
"edx.bi.user.account.authenticated",
{
'category': "conversion",
'label': registration_course_id
},
context={
'Google Analytics': {
'clientId': tracking_context.get('client_id')
}
}
)
request.session['registration_course_id'] = None
if user is not None and user.is_active:
try:
# We do not log here, because we have a handler registered
......@@ -1383,6 +1416,33 @@ def create_account(request, post_override=None): # pylint: disable-msg=too-many
(user, profile, registration) = ret
dog_stats_api.increment("common.student.account_created")
email = post_vars['email']
# Track the user's registration
if settings.FEATURES.get('SEGMENT_IO_LMS') and hasattr(settings, 'SEGMENT_IO_LMS_KEY'):
tracking_context = tracker.get_tracker().resolve_context()
analytics.identify(anonymous_id_for_user(user, None), {
email: email,
username: username,
})
registration_course_id = request.session.get('registration_course_id')
analytics.track(
user.id,
"edx.bi.user.account.registered",
{
"category": "conversion",
"label": registration_course_id
},
context={
'Google Analytics': {
'clientId': tracking_context.get('client_id')
}
}
)
request.session['registration_course_id'] = None
create_comments_service_user(user)
context = {
......
......@@ -282,7 +282,7 @@ class IntegrationTest(testutil.TestCase, test.TestCase):
def assert_register_response_before_pipeline_looks_correct(self, response):
"""Asserts a GET of /register not in the pipeline looks correct."""
self.assertEqual(200, response.status_code)
self.assertIn('Sign in with ' + self.PROVIDER_CLASS.NAME, response.content)
self.assertIn('Sign up with ' + self.PROVIDER_CLASS.NAME, response.content)
self.assert_signin_button_looks_functional(response.content, pipeline.AUTH_ENTRY_REGISTER)
def assert_signin_button_looks_functional(self, content, auth_entry):
......
......@@ -90,75 +90,7 @@ window.parseQueryString = function(queryString) {
return parameters
};
// Check if the user recently enrolled in a course by looking at a referral URL
window.checkRecentEnrollment = function(referrer) {
var enrolledIn = null;
// Check if the referrer URL contains a query string
if (referrer.indexOf("?") > -1) {
referrerQueryString = referrer.split("?")[1];
} else {
referrerQueryString = "";
}
if (referrerQueryString != "") {
// Convert a non-empty query string into a key/value object
var referrerParameters = window.parseQueryString(referrerQueryString);
if ("course_id" in referrerParameters && "enrollment_action" in referrerParameters) {
if (referrerParameters.enrollment_action == "enroll") {
enrolledIn = referrerParameters.course_id;
}
}
}
return enrolledIn
};
window.assessUserSignIn = function(parameters, userID, email, username) {
// Check if the user has logged in to enroll in a course - designed for when "Register" button registers users on click (currently, this could indicate a course registration when there may not have yet been one)
var enrolledIn = window.checkRecentEnrollment(document.referrer);
// Check if the user has just registered
if (parameters.signin == "initial") {
window.trackAccountRegistration(enrolledIn, userID, email, username);
} else {
window.trackReturningUserSignIn(enrolledIn, userID, email, username);
}
};
window.trackAccountRegistration = function(enrolledIn, userID, email, username) {
// Alias the user's anonymous history with the user's new identity (for Mixpanel)
analytics.alias(userID);
// Map the user's activity to their newly assigned ID
analytics.identify(userID, {
email: email,
username: username
});
// Track the user's account creation
analytics.track("edx.bi.user.account.registered", {
category: "conversion",
label: enrolledIn != null ? enrolledIn : "none"
});
};
window.trackReturningUserSignIn = function(enrolledIn, userID, email, username) {
// Map the user's activity to their assigned ID
analytics.identify(userID, {
email: email,
username: username
});
// Track the user's sign in
analytics.track("edx.bi.user.account.authenticated", {
category: "conversion",
label: enrolledIn != null ? enrolledIn : "none"
});
};
window.identifyUser = function(userID, email, username) {
// If the signin parameter isn't present but the query string is non-empty, map the user's activity to their assigned ID
analytics.identify(userID, {
email: email,
username: username
......
......@@ -44,12 +44,6 @@ FEEDBACK_SUBMISSION_EMAIL = "dummy@example.com"
WIKI_ENABLED = True
LOGGING = get_logger_config(ENV_ROOT / "log",
logging_env="dev",
local_loglevel="DEBUG",
dev_env=True,
debug=True)
DJFS = {
'type': 'osfs',
'directory_root': 'lms/static/djpyfs',
......
......@@ -34,7 +34,7 @@ def run():
# Initialize Segment.io analytics module. Flushes first time a message is received and
# every 50 messages thereafter, or if 10 seconds have passed since last flush
if settings.FEATURES.get('SEGMENT_IO_LMS') and settings.SEGMENT_IO_LMS_KEY:
if settings.FEATURES.get('SEGMENT_IO_LMS') and hasattr(settings, 'SEGMENT_IO_LMS_KEY'):
analytics.init(settings.SEGMENT_IO_LMS_KEY, flush_at=50)
......
......@@ -12,18 +12,8 @@
// Access the query string, stripping the leading "?"
var queryString = window.location.search.substring(1);
if (queryString != "") {
// Convert the query string to a key/value object
var parameters = window.parseQueryString(queryString);
window.identifyUser("${user.id}", "${user.email}", "${user.username}");
if ("signin" in parameters) {
window.assessUserSignIn(parameters, "${user.id}", "${user.email}", "${user.username}");
} else {
window.identifyUser("${user.id}", "${user.email}", "${user.username}");
}
} else {
window.identifyUser("${user.id}", "${user.email}", "${user.username}");
}
% endif
// Get current page URL
......
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