def post(self, request): """Handle various actions available on page""" if not request.user.is_staff: raise Http404 action = request.POST.get('action', '') track_views.server_track(request, action, {}, page='user_sysdashboard') if action == 'create_user': uname = request.POST.get('student_uname', '').strip() name = request.POST.get('student_fullname', '').strip() password = request.POST.get('student_password', '').strip() self.msg = HTML(u'<h4>{0}</h4><p>{1}</p><hr />{2}').format( _('Create User Results'), self.create_user(uname, name, password), self.msg) elif action == 'del_user': uname = request.POST.get('student_uname', '').strip() self.msg = HTML(u'<h4>{0}</h4><p>{1}</p><hr />{2}').format( _('Delete User Results'), self.delete_user(uname), self.msg) context = { 'datatable': self.make_datatable(), 'msg': self.msg, 'djangopid': os.getpid(), 'modeflag': { 'users': 'active-section' }, } return render_to_response(self.template_name, context)
def calculate(request): ''' Calculator in footer of every page. ''' equation = request.GET['equation'] try: result = calc.evaluator({}, {}, equation) except: # lint-amnesty, pylint: disable=bare-except event = {'error': list(map(str, sys.exc_info())), 'equation': equation} track_views.server_track(request, 'error:calc', event, page='calc') return HttpResponse(json.dumps({'result': 'Invalid syntax'})) # lint-amnesty, pylint: disable=http-response-with-json-dumps return HttpResponse(json.dumps({'result': str(result)})) # lint-amnesty, pylint: disable=http-response-with-json-dumps
def post(self, request): """Handle all actions from courses view""" if not request.user.is_staff: raise Http404 action = request.POST.get('action', '') track_views.server_track(request, action, {}, page='courses_sysdashboard') courses = {course.id: course for course in self.get_courses()} if action == 'add_course': gitloc = request.POST.get('repo_location', '').strip().replace(' ', '').replace(';', '') branch = request.POST.get('repo_branch', '').strip().replace(' ', '').replace(';', '') self.msg += self.get_course_from_git(gitloc, branch) elif action == 'del_course': course_id = request.POST.get('course_id', '').strip() course_key = CourseKey.from_string(course_id) course_found = False if course_key in courses: course_found = True course = courses[course_key] else: try: course = get_course_by_id(course_key) course_found = True except Exception as err: # pylint: disable=broad-except self.msg += _( # lint-amnesty, pylint: disable=translation-of-non-string HTML( u'Error - cannot get course with ID {0}<br/><pre>{1}</pre>' )).format(course_key, escape(str(err))) if course_found: # delete course that is stored with mongodb backend self.def_ms.delete_course(course.id, request.user.id) # don't delete user permission groups, though self.msg += \ HTML(u"<font color='red'>{0} {1} = {2} ({3})</font>").format( _('Deleted'), text_type(course.location), text_type(course.id), course.display_name) context = { 'datatable': self.make_datatable(list(courses.values())), 'msg': self.msg, 'djangopid': os.getpid(), 'modeflag': { 'courses': 'active-section' }, } return render_to_response(self.template_name, context)
def change_email_settings(request): """ Modify logged-in user's setting for receiving emails from a course. """ user = request.user course_id = request.data.get("course_id") receive_emails = request.data.get("receive_emails") course_key = CourseKey.from_string(course_id) if receive_emails: optout_object = Optout.objects.filter(user=user, course_id=course_key) if optout_object: optout_object.delete() log.info( "User %s (%s) opted in to receive emails from course %s", user.username, user.email, course_id, ) track_views.server_track( request, "change-email-settings", { "receive_emails": "yes", "course": course_id }, page='dashboard', ) else: Optout.objects.get_or_create(user=user, course_id=course_key) log.info( "User %s (%s) opted out of receiving emails from course %s", user.username, user.email, course_id, ) track_views.server_track( request, "change-email-settings", { "receive_emails": "no", "course": course_id }, page='dashboard', ) return JsonResponse({"success": True})
def test_server_track_with_no_request(self): request = None views.server_track(request, str(sentinel.event_type), '{}') expected_event = { 'timestamp': FROZEN_TIME, 'data': '{}', 'name': str(sentinel.event_type), 'context': { 'username': '******', 'page': None, 'event_source': 'server' } } actual_event = self.get_event() assert_event_matches(expected_event, actual_event)
def test_server_track_with_middleware_and_google_analytics_cookie(self): middleware = TrackMiddleware() request = self.request_factory.get(self.path_with_course) request.COOKIES['_ga'] = 'GA1.2.1033501218.1368477899' middleware.process_request(request) # The middleware emits an event, reset the mock to ignore it since we aren't testing that feature. self.mock_tracker.reset_mock() try: views.server_track(request, str(sentinel.event_type), '{}') expected_event = { 'timestamp': FROZEN_TIME, 'data': '{"GET": {}, "POST": {}}', 'name': self.path_with_course, 'context': { 'username': '******', 'user_id': '', 'accept_language': '', 'ip': '127.0.0.1', 'org_id': 'foo', 'agent': '', 'event_source': 'server', 'host': 'testserver', 'session': '', 'referer': '', 'client_id': '1033501218.1368477899', 'course_id': 'foo/bar/baz', 'enterprise_uuid': '', 'path': self.path_with_course, 'page': None } } finally: middleware.process_response(request, None) actual_event = self.get_event() assert_event_matches(expected_event, actual_event, tolerate={ 'string_payload', })
def process_request(self, request): try: self.enter_request_context(request) if not self.should_process_request(request): return # Removes passwords from the tracking logs # WARNING: This list needs to be changed whenever we change # password handling functionality. # # As of the time of this comment, only 'password' is used # The rest are there for future extension. # # Passwords should never be sent as GET requests, but # this can happen due to older browser bugs. We censor # this too. # # We should manually confirm no passwords make it into log # files when we change this. censored_strings = ['password', 'newpassword', 'new_password', 'oldpassword', 'old_password', 'new_password1', 'new_password2'] post_dict = dict(request.POST) get_dict = dict(request.GET) for string in censored_strings: if string in post_dict: post_dict[string] = '*' * 8 if string in get_dict: get_dict[string] = '*' * 8 event = { 'GET': dict(get_dict), 'POST': dict(post_dict), } # TODO: Confirm no large file uploads event = json.dumps(event) event = event[:512] views.server_track(request, request.META['PATH_INFO'], event) except: ## Why do we have the overly broad except? ## ## I added instrumentation so if we drop events on the ## floor, we at least know about it. However, we really ## should just return a 500 here: (1) This will translate ## to much more insidious user-facing bugs if we make any ## decisions based on incorrect data. (2) If the system ## is down, we should fail and fix it. event = {'event-type': 'exception', 'exception': repr(sys.exc_info()[0])} try: views.server_track(request, request.META['PATH_INFO'], event) except: # At this point, things are really broken. We really # should fail return a 500 to the user here. However, # the interim decision is to just fail in order to be # consistent with current policy, and expedite the PR. # This version of the code makes no compromises # relative to the code before, while a proper failure # here would involve shifting compromises and # discussion. pass
def function(event_type, event): return track_views.server_track(current_request, event_type, event, page='x_module')