Commit 48bd12c7 authored by GitLab Bot's avatar GitLab Bot

Automatic merge of gitlab-org/gitlab-ce master

parents 7552d3ba db35914c
# frozen_string_literal: true
# == RecordUserLastActivity
#
# Controller concern that updates the `last_activity_on` field of `users`
# for any authenticated GET request. The DB update will only happen once per day.
#
# In order to determine if you should include this concern or not, please check the
# description and discussion on this issue: https://gitlab.com/gitlab-org/gitlab-ce/issues/54947
module RecordUserLastActivity
include CookiesHelper
extend ActiveSupport::Concern
included do
before_action :set_user_last_activity
end
def set_user_last_activity
return unless request.get?
return unless Feature.enabled?(:set_user_last_activity, default_enabled: true)
return if Gitlab::Database.read_only?
if current_user && current_user.last_activity_on != Date.today
Users::ActivityService.new(current_user, "visited #{request.path}").execute
end
end
end
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
class Dashboard::ApplicationController < ApplicationController class Dashboard::ApplicationController < ApplicationController
include ControllerWithCrossProjectAccessCheck include ControllerWithCrossProjectAccessCheck
include RecordUserLastActivity
layout 'dashboard' layout 'dashboard'
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
class Groups::BoardsController < Groups::ApplicationController class Groups::BoardsController < Groups::ApplicationController
include BoardsResponses include BoardsResponses
include RecordUserLastActivity
before_action :assign_endpoint_vars before_action :assign_endpoint_vars
before_action :boards, only: :index before_action :boards, only: :index
......
...@@ -5,6 +5,7 @@ class GroupsController < Groups::ApplicationController ...@@ -5,6 +5,7 @@ class GroupsController < Groups::ApplicationController
include IssuableCollectionsAction include IssuableCollectionsAction
include ParamsBackwardCompatibility include ParamsBackwardCompatibility
include PreviewMarkdown include PreviewMarkdown
include RecordUserLastActivity
respond_to :html respond_to :html
......
...@@ -8,6 +8,7 @@ class Projects::IssuesController < Projects::ApplicationController ...@@ -8,6 +8,7 @@ class Projects::IssuesController < Projects::ApplicationController
include IssuableCollections include IssuableCollections
include IssuesCalendar include IssuesCalendar
include SpammableActions include SpammableActions
include RecordUserLastActivity
def issue_except_actions def issue_except_actions
%i[index calendar new create bulk_update import_csv] %i[index calendar new create bulk_update import_csv]
......
...@@ -7,6 +7,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo ...@@ -7,6 +7,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
include RendersCommits include RendersCommits
include ToggleAwardEmoji include ToggleAwardEmoji
include IssuableCollections include IssuableCollections
include RecordUserLastActivity
skip_before_action :merge_request, only: [:index, :bulk_update] skip_before_action :merge_request, only: [:index, :bulk_update]
before_action :whitelist_query_limiting, only: [:assign_related_issues, :update] before_action :whitelist_query_limiting, only: [:assign_related_issues, :update]
......
...@@ -6,6 +6,7 @@ class ProjectsController < Projects::ApplicationController ...@@ -6,6 +6,7 @@ class ProjectsController < Projects::ApplicationController
include ExtractsPath include ExtractsPath
include PreviewMarkdown include PreviewMarkdown
include SendFileUpload include SendFileUpload
include RecordUserLastActivity
prepend_before_action(only: [:show]) { authenticate_sessionless_user!(:rss) } prepend_before_action(only: [:show]) { authenticate_sessionless_user!(:rss) }
......
---
title: Update last_activity_on for Users on some main GET endpoints
merge_request: 24642
author:
type: changed
...@@ -1215,6 +1215,7 @@ The activities that update the timestamp are: ...@@ -1215,6 +1215,7 @@ The activities that update the timestamp are:
- Git HTTP/SSH activities (such as clone, push) - Git HTTP/SSH activities (such as clone, push)
- User logging in into GitLab - User logging in into GitLab
- User visiting pages related to Dashboards, Projects, Issues and Merge Requests ([introduced](https://gitlab.com/gitlab-org/gitlab-ce/issues/54947) in GitLab 11.8)
By default, it shows the activity for all users in the last 6 months, but this can be By default, it shows the activity for all users in the last 6 months, but this can be
amended by using the `from` parameter. amended by using the `from` parameter.
......
...@@ -19,7 +19,7 @@ comes pre-installed on GNU/Linux and macOS, but not on Windows. ...@@ -19,7 +19,7 @@ comes pre-installed on GNU/Linux and macOS, but not on Windows.
Depending on your Windows version, there are different methods to work with Depending on your Windows version, there are different methods to work with
SSH keys. SSH keys.
### Installing the SSH client for Windows 10 ### Windows 10: Windows Subsystem for Linux
Starting with Windows 10, you can Starting with Windows 10, you can
[install the Windows Subsystem for Linux (WSL)](https://docs.microsoft.com/en-us/windows/wsl/install-win10) [install the Windows Subsystem for Linux (WSL)](https://docs.microsoft.com/en-us/windows/wsl/install-win10)
...@@ -27,10 +27,10 @@ where you can run Linux distributions directly on Windows, without the overhead ...@@ -27,10 +27,10 @@ where you can run Linux distributions directly on Windows, without the overhead
of a virtual machine. Once installed and set up, you'll have the Git and SSH of a virtual machine. Once installed and set up, you'll have the Git and SSH
clients at your disposal. clients at your disposal.
### Installing the SSH client for Windows 8.1 and Windows 7 ### Windows 10, 8.1, and 7: Git for Windows
The easiest way to install Git and the SSH client on Windows 8.1 and Windows 7 The easiest way to install Git and the SSH client on Windows 8.1 and Windows 7
is [Git for Windows](https://gitforwindows.org). It provides a BASH is [Git for Windows](https://gitforwindows.org). It provides a Bash
emulation (Git Bash) used for running Git from the command line and the emulation (Git Bash) used for running Git from the command line and the
`ssh-keygen` command that is useful to create SSH keys as you'll learn below. `ssh-keygen` command that is useful to create SSH keys as you'll learn below.
......
...@@ -25,3 +25,4 @@ How do we measure the activity of users? GitLab considers a user active if: ...@@ -25,3 +25,4 @@ How do we measure the activity of users? GitLab considers a user active if:
- The user signs in. - The user signs in.
- The user has Git activity (whether push or pull). - The user has Git activity (whether push or pull).
- The user visits pages related to Dashboards, Projects, Issues and Merge Requests ([introduced](https://gitlab.com/gitlab-org/gitlab-ce/issues/54947) in GitLab 11.8).
# frozen_string_literal: true
require 'spec_helper'
describe 'Update of user activity' do
let(:user) { create(:user, last_activity_on: nil) }
before do
group = create(:group, name: 'group')
project = create(:project, :public, namespace: group, name: 'project')
create(:issue, project: project, iid: 10)
create(:merge_request, source_project: project, iid: 15)
project.add_maintainer(user)
end
paths_to_visit = [
'/group',
'/group/project',
'/groups/group/-/issues',
'/groups/group/-/boards',
'/dashboard/projects',
'/dashboard/snippets',
'/dashboard/groups',
'/dashboard/todos',
'/group/project/issues',
'/group/project/issues/10',
'/group/project/merge_requests',
'/group/project/merge_requests/15'
]
context 'without an authenticated user' do
it 'does not set the last activity cookie' do
get "/group/project"
expect(response.cookies['user_last_activity_on']).to be_nil
end
end
context 'with an authenticated user' do
before do
login_as(user)
end
context 'with a POST request' do
it 'does not set the last activity cookie' do
post "/group/project/archive"
expect(response.cookies['user_last_activity_on']).to be_nil
end
end
paths_to_visit.each do |path|
context "on GET to #{path}" do
it 'updates the last activity date' do
expect(Users::ActivityService).to receive(:new).and_call_original
get path
expect(user.last_activity_on).to eq(Date.today)
end
context 'when calling it twice' do
it 'updates last_activity_on just once' do
expect(Users::ActivityService).to receive(:new).once.and_call_original
2.times do
get path
end
end
end
context 'when last_activity_on is nil' do
before do
user.update_attribute(:last_activity_on, nil)
end
it 'updates the last activity date' do
expect(user.last_activity_on).to be_nil
get path
expect(user.last_activity_on).to eq(Date.today)
end
end
context 'when last_activity_on is stale' do
before do
user.update_attribute(:last_activity_on, 2.days.ago.to_date)
end
it 'updates the last activity date' do
get path
expect(user.last_activity_on).to eq(Date.today)
end
end
context 'when last_activity_on is up to date' do
before do
user.update_attribute(:last_activity_on, Date.today)
end
it 'does not try to update it' do
expect(Users::ActivityService).not_to receive(:new)
get path
end
end
end
end
end
end
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