Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouwe Maan <douwe@gitlab.com>2018-05-02 14:56:47 +0300
committerDouwe Maan <douwe@gitlab.com>2018-05-02 14:56:47 +0300
commite3b15d37180b49949e1ea19210f3ea219b645ec1 (patch)
tree1e070cf5943034b85a8ddc74301681814301ed84
parent75f6e91fcde12029068f48b6b7fb3fd13a612c61 (diff)
Revert "Merge branch 'feature/display-active-sessions' into 'master'"revert-1350d80c
This reverts merge request !17867
-rw-r--r--Gemfile3
-rw-r--r--Gemfile.lock2
-rw-r--r--app/assets/stylesheets/framework/common.scss1
-rw-r--r--app/assets/stylesheets/framework/images.scss35
-rw-r--r--app/controllers/profiles/active_sessions_controller.rb14
-rw-r--r--app/helpers/active_sessions_helper.rb23
-rw-r--r--app/models/active_session.rb110
-rw-r--r--app/views/layouts/nav/sidebar/_profile.html.haml11
-rw-r--r--app/views/profiles/active_sessions/_active_session.html.haml31
-rw-r--r--app/views/profiles/active_sessions/index.html.haml14
-rw-r--r--changelogs/unreleased/feature-display-active-sessions.yml5
-rw-r--r--config/initializers/session_store.rb26
-rw-r--r--config/initializers/warden.rb12
-rw-r--r--config/routes/profile.rb1
-rw-r--r--doc/development/fe_guide/icons.md2
-rw-r--r--doc/user/profile/active_sessions.md20
-rw-r--r--doc/user/profile/img/active_sessions_list.pngbin41649 -> 0 bytes
-rw-r--r--doc/user/profile/index.md1
-rw-r--r--lib/gitlab/redis/shared_state.rb2
-rw-r--r--spec/controllers/projects/clusters/gcp_controller_spec.rb2
-rw-r--r--spec/features/profiles/active_sessions_spec.rb89
-rw-r--r--spec/features/users/active_sessions_spec.rb69
-rw-r--r--spec/models/active_session_spec.rb216
23 files changed, 47 insertions, 642 deletions
diff --git a/Gemfile b/Gemfile
index a68b044b39e..caeaae96164 100644
--- a/Gemfile
+++ b/Gemfile
@@ -184,9 +184,6 @@ gem 're2', '~> 1.1.1'
gem 'version_sorter', '~> 2.1.0'
-# User agent parsing
-gem 'device_detector'
-
# Cache
gem 'redis-rails', '~> 5.0.2'
diff --git a/Gemfile.lock b/Gemfile.lock
index f11df6a283e..9b2c47587ee 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -161,7 +161,6 @@ GEM
activerecord (>= 3.2.0, < 5.1)
descendants_tracker (0.0.4)
thread_safe (~> 0.3, >= 0.3.1)
- device_detector (1.0.0)
devise (4.2.0)
bcrypt (~> 3.0)
orm_adapter (~> 0.1)
@@ -1027,7 +1026,6 @@ DEPENDENCIES
database_cleaner (~> 1.5.0)
deckar01-task_list (= 2.0.0)
default_value_for (~> 3.0.0)
- device_detector
devise (~> 4.2)
devise-two-factor (~> 3.0.0)
diffy (~> 3.1.0)
diff --git a/app/assets/stylesheets/framework/common.scss b/app/assets/stylesheets/framework/common.scss
index 2faea55a5f5..e058a0b35b7 100644
--- a/app/assets/stylesheets/framework/common.scss
+++ b/app/assets/stylesheets/framework/common.scss
@@ -452,7 +452,6 @@ img.emoji {
/** COMMON CLASSES **/
.prepend-top-0 { margin-top: 0; }
-.prepend-top-2 { margin-top: 2px; }
.prepend-top-5 { margin-top: 5px; }
.prepend-top-8 { margin-top: $grid-size; }
.prepend-top-10 { margin-top: 10px; }
diff --git a/app/assets/stylesheets/framework/images.scss b/app/assets/stylesheets/framework/images.scss
index ab3cceceae9..62a0fba3da3 100644
--- a/app/assets/stylesheets/framework/images.scss
+++ b/app/assets/stylesheets/framework/images.scss
@@ -39,10 +39,35 @@
svg {
fill: currentColor;
- $svg-sizes: 8 12 16 18 24 32 48 72;
- @each $svg-size in $svg-sizes {
- &.s#{$svg-size} {
- @include svg-size(#{$svg-size}px);
- }
+ &.s8 {
+ @include svg-size(8px);
+ }
+
+ &.s12 {
+ @include svg-size(12px);
+ }
+
+ &.s16 {
+ @include svg-size(16px);
+ }
+
+ &.s18 {
+ @include svg-size(18px);
+ }
+
+ &.s24 {
+ @include svg-size(24px);
+ }
+
+ &.s32 {
+ @include svg-size(32px);
+ }
+
+ &.s48 {
+ @include svg-size(48px);
+ }
+
+ &.s72 {
+ @include svg-size(72px);
}
}
diff --git a/app/controllers/profiles/active_sessions_controller.rb b/app/controllers/profiles/active_sessions_controller.rb
deleted file mode 100644
index f0cdc228366..00000000000
--- a/app/controllers/profiles/active_sessions_controller.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-class Profiles::ActiveSessionsController < Profiles::ApplicationController
- def index
- @sessions = ActiveSession.list(current_user)
- end
-
- def destroy
- ActiveSession.destroy(current_user, params[:id])
-
- respond_to do |format|
- format.html { redirect_to profile_active_sessions_url, status: 302 }
- format.js { head :ok }
- end
- end
-end
diff --git a/app/helpers/active_sessions_helper.rb b/app/helpers/active_sessions_helper.rb
deleted file mode 100644
index 97b6dac67c5..00000000000
--- a/app/helpers/active_sessions_helper.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-module ActiveSessionsHelper
- # Maps a device type as defined in `ActiveSession` to an svg icon name and
- # outputs the icon html.
- #
- # see `DeviceDetector::Device::DEVICE_NAMES` about the available device types
- def active_session_device_type_icon(active_session)
- icon_name =
- case active_session.device_type
- when 'smartphone', 'feature phone', 'phablet'
- 'mobile'
- when 'tablet'
- 'tablet'
- when 'tv', 'smart display', 'camera', 'portable media player', 'console'
- 'media'
- when 'car browser'
- 'car'
- else
- 'monitor-o'
- end
-
- sprite_icon(icon_name, size: 16, css_class: 'prepend-top-2')
- end
-end
diff --git a/app/models/active_session.rb b/app/models/active_session.rb
deleted file mode 100644
index b4a86dbb331..00000000000
--- a/app/models/active_session.rb
+++ /dev/null
@@ -1,110 +0,0 @@
-class ActiveSession
- include ActiveModel::Model
-
- attr_accessor :created_at, :updated_at,
- :session_id, :ip_address,
- :browser, :os, :device_name, :device_type
-
- def current?(session)
- return false if session_id.nil? || session.id.nil?
-
- session_id == session.id
- end
-
- def human_device_type
- device_type&.titleize
- end
-
- def self.set(user, request)
- Gitlab::Redis::SharedState.with do |redis|
- session_id = request.session.id
- client = DeviceDetector.new(request.user_agent)
- timestamp = Time.current
-
- active_user_session = new(
- ip_address: request.ip,
- browser: client.name,
- os: client.os_name,
- device_name: client.device_name,
- device_type: client.device_type,
- created_at: user.current_sign_in_at || timestamp,
- updated_at: timestamp,
- session_id: session_id
- )
-
- redis.pipelined do
- redis.setex(
- key_name(user.id, session_id),
- Settings.gitlab['session_expire_delay'] * 60,
- Marshal.dump(active_user_session)
- )
-
- redis.sadd(
- lookup_key_name(user.id),
- session_id
- )
- end
- end
- end
-
- def self.list(user)
- Gitlab::Redis::SharedState.with do |redis|
- cleaned_up_lookup_entries(redis, user.id).map do |entry|
- # rubocop:disable Security/MarshalLoad
- Marshal.load(entry)
- # rubocop:enable Security/MarshalLoad
- end
- end
- end
-
- def self.destroy(user, session_id)
- Gitlab::Redis::SharedState.with do |redis|
- redis.srem(lookup_key_name(user.id), session_id)
-
- deleted_keys = redis.del(key_name(user.id, session_id))
-
- # only allow deleting the devise session if we could actually find a
- # related active session. this prevents another user from deleting
- # someone else's session.
- if deleted_keys > 0
- redis.del("#{Gitlab::Redis::SharedState::SESSION_NAMESPACE}:#{session_id}")
- end
- end
- end
-
- def self.cleanup(user)
- Gitlab::Redis::SharedState.with do |redis|
- cleaned_up_lookup_entries(redis, user.id)
- end
- end
-
- def self.key_name(user_id, session_id = '*')
- "#{Gitlab::Redis::SharedState::USER_SESSIONS_NAMESPACE}:#{user_id}:#{session_id}"
- end
-
- def self.lookup_key_name(user_id)
- "#{Gitlab::Redis::SharedState::USER_SESSIONS_LOOKUP_NAMESPACE}:#{user_id}"
- end
-
- def self.cleaned_up_lookup_entries(redis, user_id)
- lookup_key = lookup_key_name(user_id)
-
- session_ids = redis.smembers(lookup_key)
-
- entry_keys = session_ids.map { |session_id| key_name(user_id, session_id) }
- return [] if entry_keys.empty?
-
- entries = redis.mget(entry_keys)
-
- session_ids_and_entries = session_ids.zip(entries)
-
- # remove expired keys.
- # only the single key entries are automatically expired by redis, the
- # lookup entries in the set need to be removed manually.
- session_ids_and_entries.reject { |_session_id, entry| entry }.each do |session_id, _entry|
- redis.srem(lookup_key, session_id)
- end
-
- session_ids_and_entries.select { |_session_id, entry| entry }.map { |_session_id, entry| entry }
- end
-end
diff --git a/app/views/layouts/nav/sidebar/_profile.html.haml b/app/views/layouts/nav/sidebar/_profile.html.haml
index 6cbd163dd41..c878fcf2808 100644
--- a/app/views/layouts/nav/sidebar/_profile.html.haml
+++ b/app/views/layouts/nav/sidebar/_profile.html.haml
@@ -129,17 +129,6 @@
= link_to profile_preferences_path do
%strong.fly-out-top-item-name
#{ _('Preferences') }
- = nav_link(controller: :active_sessions) do
- = link_to profile_active_sessions_path do
- .nav-icon-container
- = sprite_icon('monitor-lines')
- %span.nav-item-name
- Active Sessions
- %ul.sidebar-sub-level-items.is-fly-out-only
- = nav_link(controller: :active_sessions, html_options: { class: "fly-out-top-item" } ) do
- = link_to profile_active_sessions_path do
- %strong.fly-out-top-item-name
- #{ _('Active Sessions') }
= nav_link(path: 'profiles#audit_log') do
= link_to audit_log_profile_path do
.nav-icon-container
diff --git a/app/views/profiles/active_sessions/_active_session.html.haml b/app/views/profiles/active_sessions/_active_session.html.haml
deleted file mode 100644
index d40b771f48b..00000000000
--- a/app/views/profiles/active_sessions/_active_session.html.haml
+++ /dev/null
@@ -1,31 +0,0 @@
-- is_current_session = active_session.current?(session)
-
-%li
- .pull-left.append-right-10{ data: { toggle: 'tooltip' }, title: active_session.human_device_type }
- = active_session_device_type_icon(active_session)
-
- .description.pull-left
- %div
- %strong= active_session.ip_address
- - if is_current_session
- %div This is your current session
- - else
- %div
- Last accessed on
- = l(active_session.updated_at, format: :short)
-
- %div
- %strong= active_session.browser
- on
- %strong= active_session.os
-
- %div
- %strong Signed in
- on
- = l(active_session.created_at, format: :short)
-
- - unless is_current_session
- .pull-right
- = link_to profile_active_session_path(active_session.session_id), data: { confirm: 'Are you sure? The device will be signed out of GitLab.' }, method: :delete, class: "btn btn-danger prepend-left-10" do
- %span.sr-only Revoke
- Revoke
diff --git a/app/views/profiles/active_sessions/index.html.haml b/app/views/profiles/active_sessions/index.html.haml
deleted file mode 100644
index d0250bb4eab..00000000000
--- a/app/views/profiles/active_sessions/index.html.haml
+++ /dev/null
@@ -1,14 +0,0 @@
-- page_title 'Active Sessions'
-- @content_class = "limit-container-width" unless fluid_layout
-
-.row.prepend-top-default
- .col-lg-4.profile-settings-sidebar
- %h4.prepend-top-0
- = page_title
- %p
- This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize.
- .col-lg-8
- .append-bottom-default
-
- %ul.well-list
- = render partial: 'profiles/active_sessions/active_session', collection: @sessions
diff --git a/changelogs/unreleased/feature-display-active-sessions.yml b/changelogs/unreleased/feature-display-active-sessions.yml
deleted file mode 100644
index 14cfa66953e..00000000000
--- a/changelogs/unreleased/feature-display-active-sessions.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Display active sessions and allow the user to revoke any of it
-merge_request: 17867
-author: Alexis Reigel
-type: added
diff --git a/config/initializers/session_store.rb b/config/initializers/session_store.rb
index da24881885e..f2fde1e0048 100644
--- a/config/initializers/session_store.rb
+++ b/config/initializers/session_store.rb
@@ -15,15 +15,19 @@ cookie_key = if Rails.env.development?
"_gitlab_session"
end
-sessions_config = Gitlab::Redis::SharedState.params
-sessions_config[:namespace] = Gitlab::Redis::SharedState::SESSION_NAMESPACE
+if Rails.env.test?
+ Gitlab::Application.config.session_store :cookie_store, key: "_gitlab_session"
+else
+ sessions_config = Gitlab::Redis::SharedState.params
+ sessions_config[:namespace] = Gitlab::Redis::SharedState::SESSION_NAMESPACE
-Gitlab::Application.config.session_store(
- :redis_store, # Using the cookie_store would enable session replay attacks.
- servers: sessions_config,
- key: cookie_key,
- secure: Gitlab.config.gitlab.https,
- httponly: true,
- expires_in: Settings.gitlab['session_expire_delay'] * 60,
- path: Rails.application.config.relative_url_root.nil? ? '/' : Gitlab::Application.config.relative_url_root
-)
+ Gitlab::Application.config.session_store(
+ :redis_store, # Using the cookie_store would enable session replay attacks.
+ servers: sessions_config,
+ key: cookie_key,
+ secure: Gitlab.config.gitlab.https,
+ httponly: true,
+ expires_in: Settings.gitlab['session_expire_delay'] * 60,
+ path: Rails.application.config.relative_url_root.nil? ? '/' : Gitlab::Application.config.relative_url_root
+ )
+end
diff --git a/config/initializers/warden.rb b/config/initializers/warden.rb
index bf079f8e1a7..ee034d21eae 100644
--- a/config/initializers/warden.rb
+++ b/config/initializers/warden.rb
@@ -6,16 +6,4 @@ Rails.application.configure do |config|
Warden::Manager.before_failure do |env, opts|
Gitlab::Auth::BlockedUserTracker.log_if_user_blocked(env)
end
-
- Warden::Manager.after_authentication do |user, auth, opts|
- ActiveSession.cleanup(user)
- end
-
- Warden::Manager.after_set_user only: :fetch do |user, auth, opts|
- ActiveSession.set(user, auth.request)
- end
-
- Warden::Manager.before_logout do |user, auth, opts|
- ActiveSession.destroy(user || auth.user, auth.request.session.id)
- end
end
diff --git a/config/routes/profile.rb b/config/routes/profile.rb
index a9ba5ac2c0b..bcfc17a5f66 100644
--- a/config/routes/profile.rb
+++ b/config/routes/profile.rb
@@ -30,7 +30,6 @@ resource :profile, only: [:show, :update] do
put :revoke
end
end
- resources :active_sessions, only: [:index, :destroy]
resources :emails, only: [:index, :create, :destroy] do
member do
put :resend_confirmation_instructions
diff --git a/doc/development/fe_guide/icons.md b/doc/development/fe_guide/icons.md
index b469a9c6aef..b288ee95722 100644
--- a/doc/development/fe_guide/icons.md
+++ b/doc/development/fe_guide/icons.md
@@ -49,7 +49,7 @@ Please use the following function inside JS to render an icon :
All Icons and Illustrations are managed in the [gitlab-svgs](https://gitlab.com/gitlab-org/gitlab-svgs) repository which is added as a dev-dependency.
-To upgrade to a new SVG Sprite version run `yarn upgrade @gitlab-org/gitlab-svgs`.
+To upgrade to a new SVG Sprite version run `yarn upgrade @gitlab-org/gitlab-svgs` and then run `yarn run svg`. This task will copy the svg sprite and all illustrations in the correct folders. The updated files should be tracked in Git as those are referenced.
# SVG Illustrations
diff --git a/doc/user/profile/active_sessions.md b/doc/user/profile/active_sessions.md
deleted file mode 100644
index 5119c0e30d0..00000000000
--- a/doc/user/profile/active_sessions.md
+++ /dev/null
@@ -1,20 +0,0 @@
-# Active Sessions
-
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/17867)
-> in GitLab 10.8.
-
-GitLab lists all devices that have logged into your account. This allows you to
-review the sessions and revoke any of it that you don't recognize.
-
-## Listing all active sessions
-
-1. On the upper right corner, click on your avatar and go to your **Settings**.
-1. Navigate to the **Active Sessions** tab.
-
-![Active sessions list](img/active_sessions_list.png)
-
-## Revoking a session
-
-1. Navigate to your [profile's](#profile-settings) **Settings > Active Sessions**.
-1. Click on **Revoke** besides a session. The current session cannot be
- revoked, as this would sign you out of GitLab.
diff --git a/doc/user/profile/img/active_sessions_list.png b/doc/user/profile/img/active_sessions_list.png
deleted file mode 100644
index 76a52220bcd..00000000000
--- a/doc/user/profile/img/active_sessions_list.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/profile/index.md b/doc/user/profile/index.md
index 91cdef8d1dd..ab16f8d14c1 100644
--- a/doc/user/profile/index.md
+++ b/doc/user/profile/index.md
@@ -39,7 +39,6 @@ From there, you can:
- Manage [SSH keys](../../ssh/README.md#ssh) to access your account via SSH
- Manage your [preferences](preferences.md#syntax-highlighting-theme)
to customize your own GitLab experience
-- [View your active sessions](active_sessions.md) and revoke any of them if necessary
- Access your audit log, a security log of important events involving your account
## Changing your username
diff --git a/lib/gitlab/redis/shared_state.rb b/lib/gitlab/redis/shared_state.rb
index e5a0fdae7ef..10bec7a90da 100644
--- a/lib/gitlab/redis/shared_state.rb
+++ b/lib/gitlab/redis/shared_state.rb
@@ -5,8 +5,6 @@ module Gitlab
module Redis
class SharedState < ::Gitlab::Redis::Wrapper
SESSION_NAMESPACE = 'session:gitlab'.freeze
- USER_SESSIONS_NAMESPACE = 'session:user:gitlab'.freeze
- USER_SESSIONS_LOOKUP_NAMESPACE = 'session:lookup:user:gitlab'.freeze
DEFAULT_REDIS_SHARED_STATE_URL = 'redis://localhost:6382'.freeze
REDIS_SHARED_STATE_CONFIG_ENV_VAR_NAME = 'GITLAB_REDIS_SHARED_STATE_CONFIG_FILE'.freeze
diff --git a/spec/controllers/projects/clusters/gcp_controller_spec.rb b/spec/controllers/projects/clusters/gcp_controller_spec.rb
index 715bb9f5e52..e14ba29fa70 100644
--- a/spec/controllers/projects/clusters/gcp_controller_spec.rb
+++ b/spec/controllers/projects/clusters/gcp_controller_spec.rb
@@ -142,7 +142,7 @@ describe Projects::Clusters::GcpController do
context 'when google project billing is enabled' do
before do
- redis_double = double.as_null_object
+ redis_double = double
allow(Gitlab::Redis::SharedState).to receive(:with).and_yield(redis_double)
allow(redis_double).to receive(:get).with(CheckGcpProjectBillingWorker.redis_shared_state_key_for('token')).and_return('true')
end
diff --git a/spec/features/profiles/active_sessions_spec.rb b/spec/features/profiles/active_sessions_spec.rb
deleted file mode 100644
index 4045cfd21c4..00000000000
--- a/spec/features/profiles/active_sessions_spec.rb
+++ /dev/null
@@ -1,89 +0,0 @@
-require 'rails_helper'
-
-feature 'Profile > Active Sessions', :clean_gitlab_redis_shared_state do
- let(:user) do
- create(:user).tap do |user|
- user.current_sign_in_at = Time.current
- end
- end
-
- around do |example|
- Timecop.freeze(Time.zone.parse('2018-03-12 09:06')) do
- example.run
- end
- end
-
- scenario 'User sees their active sessions' do
- Capybara::Session.new(:session1)
- Capybara::Session.new(:session2)
-
- # note: headers can only be set on the non-js (aka. rack-test) driver
- using_session :session1 do
- Capybara.page.driver.header(
- 'User-Agent',
- 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:58.0) Gecko/20100101 Firefox/58.0'
- )
-
- gitlab_sign_in(user)
- end
-
- # set an additional session on another device
- using_session :session2 do
- Capybara.page.driver.header(
- 'User-Agent',
- 'Mozilla/5.0 (iPhone; CPU iPhone OS 8_1_3 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Mobile/12B466 [FBDV/iPhone7,2]'
- )
-
- gitlab_sign_in(user)
- end
-
- using_session :session1 do
- visit profile_active_sessions_path
-
- expect(page).to have_content(
- '127.0.0.1 ' \
- 'This is your current session ' \
- 'Firefox on Ubuntu ' \
- 'Signed in on 12 Mar 09:06'
- )
-
- expect(page).to have_selector '[title="Desktop"]', count: 1
-
- expect(page).to have_content(
- '127.0.0.1 ' \
- 'Last accessed on 12 Mar 09:06 ' \
- 'Mobile Safari on iOS ' \
- 'Signed in on 12 Mar 09:06'
- )
-
- expect(page).to have_selector '[title="Smartphone"]', count: 1
- end
- end
-
- scenario 'User can revoke a session', :js, :redis_session_store do
- Capybara::Session.new(:session1)
- Capybara::Session.new(:session2)
-
- # set an additional session in another browser
- using_session :session2 do
- gitlab_sign_in(user)
- end
-
- using_session :session1 do
- gitlab_sign_in(user)
- visit profile_active_sessions_path
-
- expect(page).to have_link('Revoke', count: 1)
-
- accept_confirm { click_on 'Revoke' }
-
- expect(page).not_to have_link('Revoke')
- end
-
- using_session :session2 do
- visit profile_active_sessions_path
-
- expect(page).to have_content('You need to sign in or sign up before continuing.')
- end
- end
-end
diff --git a/spec/features/users/active_sessions_spec.rb b/spec/features/users/active_sessions_spec.rb
deleted file mode 100644
index 631d7e3bced..00000000000
--- a/spec/features/users/active_sessions_spec.rb
+++ /dev/null
@@ -1,69 +0,0 @@
-require 'spec_helper'
-
-feature 'Active user sessions', :clean_gitlab_redis_shared_state do
- scenario 'Successful login adds a new active user login' do
- now = Time.zone.parse('2018-03-12 09:06')
- Timecop.freeze(now) do
- user = create(:user)
- gitlab_sign_in(user)
- expect(current_path).to eq root_path
-
- sessions = ActiveSession.list(user)
- expect(sessions.count).to eq 1
-
- # refresh the current page updates the updated_at
- Timecop.freeze(now + 1.minute) do
- visit current_path
-
- sessions = ActiveSession.list(user)
- expect(sessions.first).to have_attributes(
- created_at: Time.zone.parse('2018-03-12 09:06'),
- updated_at: Time.zone.parse('2018-03-12 09:07')
- )
- end
- end
- end
-
- scenario 'Successful login cleans up obsolete entries' do
- user = create(:user)
-
- Gitlab::Redis::SharedState.with do |redis|
- redis.sadd("session:lookup:user:gitlab:#{user.id}", '59822c7d9fcdfa03725eff41782ad97d')
- end
-
- gitlab_sign_in(user)
-
- Gitlab::Redis::SharedState.with do |redis|
- expect(redis.smembers("session:lookup:user:gitlab:#{user.id}")).not_to include '59822c7d9fcdfa03725eff41782ad97d'
- end
- end
-
- scenario 'Sessionless login does not clean up obsolete entries' do
- user = create(:user)
- personal_access_token = create(:personal_access_token, user: user)
-
- Gitlab::Redis::SharedState.with do |redis|
- redis.sadd("session:lookup:user:gitlab:#{user.id}", '59822c7d9fcdfa03725eff41782ad97d')
- end
-
- visit user_path(user, :atom, private_token: personal_access_token.token)
- expect(page.status_code).to eq 200
-
- Gitlab::Redis::SharedState.with do |redis|
- expect(redis.smembers("session:lookup:user:gitlab:#{user.id}")).to include '59822c7d9fcdfa03725eff41782ad97d'
- end
- end
-
- scenario 'Logout deletes the active user login' do
- user = create(:user)
- gitlab_sign_in(user)
- expect(current_path).to eq root_path
-
- expect(ActiveSession.list(user).count).to eq 1
-
- gitlab_sign_out
- expect(current_path).to eq new_user_session_path
-
- expect(ActiveSession.list(user)).to be_empty
- end
-end
diff --git a/spec/models/active_session_spec.rb b/spec/models/active_session_spec.rb
deleted file mode 100644
index 129b2f92683..00000000000
--- a/spec/models/active_session_spec.rb
+++ /dev/null
@@ -1,216 +0,0 @@
-require 'rails_helper'
-
-RSpec.describe ActiveSession, :clean_gitlab_redis_shared_state do
- let(:user) do
- create(:user).tap do |user|
- user.current_sign_in_at = Time.current
- end
- end
-
- let(:session) { double(:session, id: '6919a6f1bb119dd7396fadc38fd18d0d') }
-
- let(:request) do
- double(:request, {
- user_agent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 8_1_3 like Mac OS X) AppleWebKit/600.1.4 ' \
- '(KHTML, like Gecko) Mobile/12B466 [FBDV/iPhone7,2]',
- ip: '127.0.0.1',
- session: session
- })
- end
-
- describe '#current?' do
- it 'returns true if the active session matches the current session' do
- active_session = ActiveSession.new(session_id: '6919a6f1bb119dd7396fadc38fd18d0d')
-
- expect(active_session.current?(session)).to be true
- end
-
- it 'returns false if the active session does not match the current session' do
- active_session = ActiveSession.new(session_id: '59822c7d9fcdfa03725eff41782ad97d')
-
- expect(active_session.current?(session)).to be false
- end
-
- it 'returns false if the session id is nil' do
- active_session = ActiveSession.new(session_id: nil)
- session = double(:session, id: nil)
-
- expect(active_session.current?(session)).to be false
- end
- end
-
- describe '.list' do
- it 'returns all sessions by user' do
- Gitlab::Redis::SharedState.with do |redis|
- redis.set("session:user:gitlab:#{user.id}:6919a6f1bb119dd7396fadc38fd18d0d", Marshal.dump({ session_id: 'a' }))
- redis.set("session:user:gitlab:#{user.id}:59822c7d9fcdfa03725eff41782ad97d", Marshal.dump({ session_id: 'b' }))
- redis.set("session:user:gitlab:9999:5c8611e4f9c69645ad1a1492f4131358", '')
-
- redis.sadd(
- "session:lookup:user:gitlab:#{user.id}",
- %w[
- 6919a6f1bb119dd7396fadc38fd18d0d
- 59822c7d9fcdfa03725eff41782ad97d
- ]
- )
- end
-
- expect(ActiveSession.list(user)).to match_array [{ session_id: 'a' }, { session_id: 'b' }]
- end
-
- it 'does not return obsolete entries and cleans them up' do
- Gitlab::Redis::SharedState.with do |redis|
- redis.set("session:user:gitlab:#{user.id}:6919a6f1bb119dd7396fadc38fd18d0d", Marshal.dump({ session_id: 'a' }))
-
- redis.sadd(
- "session:lookup:user:gitlab:#{user.id}",
- %w[
- 6919a6f1bb119dd7396fadc38fd18d0d
- 59822c7d9fcdfa03725eff41782ad97d
- ]
- )
- end
-
- expect(ActiveSession.list(user)).to eq [{ session_id: 'a' }]
-
- Gitlab::Redis::SharedState.with do |redis|
- expect(redis.sscan_each("session:lookup:user:gitlab:#{user.id}").to_a).to eq ['6919a6f1bb119dd7396fadc38fd18d0d']
- end
- end
-
- it 'returns an empty array if the use does not have any active session' do
- expect(ActiveSession.list(user)).to eq []
- end
- end
-
- describe '.set' do
- it 'sets a new redis entry for the user session and a lookup entry' do
- ActiveSession.set(user, request)
-
- Gitlab::Redis::SharedState.with do |redis|
- expect(redis.scan_each.to_a).to match_array [
- "session:user:gitlab:#{user.id}:6919a6f1bb119dd7396fadc38fd18d0d",
- "session:lookup:user:gitlab:#{user.id}"
- ]
- end
- end
-
- it 'adds timestamps and information from the request' do
- Timecop.freeze(Time.zone.parse('2018-03-12 09:06')) do
- ActiveSession.set(user, request)
-
- session = ActiveSession.list(user)
-
- expect(session.count).to eq 1
- expect(session.first).to have_attributes(
- ip_address: '127.0.0.1',
- browser: 'Mobile Safari',
- os: 'iOS',
- device_name: 'iPhone 6',
- device_type: 'smartphone',
- created_at: Time.zone.parse('2018-03-12 09:06'),
- updated_at: Time.zone.parse('2018-03-12 09:06'),
- session_id: '6919a6f1bb119dd7396fadc38fd18d0d'
- )
- end
- end
-
- it 'keeps the created_at from the login on consecutive requests' do
- now = Time.zone.parse('2018-03-12 09:06')
-
- Timecop.freeze(now) do
- ActiveSession.set(user, request)
-
- Timecop.freeze(now + 1.minute) do
- ActiveSession.set(user, request)
-
- session = ActiveSession.list(user)
-
- expect(session.first).to have_attributes(
- created_at: Time.zone.parse('2018-03-12 09:06'),
- updated_at: Time.zone.parse('2018-03-12 09:07')
- )
- end
- end
- end
- end
-
- describe '.destroy' do
- it 'removes the entry associated with the currently killed user session' do
- Gitlab::Redis::SharedState.with do |redis|
- redis.set("session:user:gitlab:#{user.id}:6919a6f1bb119dd7396fadc38fd18d0d", '')
- redis.set("session:user:gitlab:#{user.id}:59822c7d9fcdfa03725eff41782ad97d", '')
- redis.set("session:user:gitlab:9999:5c8611e4f9c69645ad1a1492f4131358", '')
- end
-
- ActiveSession.destroy(user, request.session.id)
-
- Gitlab::Redis::SharedState.with do |redis|
- expect(redis.scan_each(match: "session:user:gitlab:*")).to match_array [
- "session:user:gitlab:#{user.id}:59822c7d9fcdfa03725eff41782ad97d",
- "session:user:gitlab:9999:5c8611e4f9c69645ad1a1492f4131358"
- ]
- end
- end
-
- it 'removes the lookup entry' do
- Gitlab::Redis::SharedState.with do |redis|
- redis.set("session:user:gitlab:#{user.id}:6919a6f1bb119dd7396fadc38fd18d0d", '')
- redis.sadd("session:lookup:user:gitlab:#{user.id}", '6919a6f1bb119dd7396fadc38fd18d0d')
- end
-
- ActiveSession.destroy(user, request.session.id)
-
- Gitlab::Redis::SharedState.with do |redis|
- expect(redis.scan_each(match: "session:lookup:user:gitlab:#{user.id}").to_a).to be_empty
- end
- end
-
- it 'removes the devise session' do
- Gitlab::Redis::SharedState.with do |redis|
- redis.set("session:user:gitlab:#{user.id}:6919a6f1bb119dd7396fadc38fd18d0d", '')
- redis.set("session:gitlab:6919a6f1bb119dd7396fadc38fd18d0d", '')
- end
-
- ActiveSession.destroy(user, request.session.id)
-
- Gitlab::Redis::SharedState.with do |redis|
- expect(redis.scan_each(match: "session:gitlab:*").to_a).to be_empty
- end
- end
-
- it 'does not remove the devise session if the active session could not be found' do
- Gitlab::Redis::SharedState.with do |redis|
- redis.set("session:gitlab:6919a6f1bb119dd7396fadc38fd18d0d", '')
- end
-
- other_user = create(:user)
-
- ActiveSession.destroy(other_user, request.session.id)
-
- Gitlab::Redis::SharedState.with do |redis|
- expect(redis.scan_each(match: "session:gitlab:*").to_a).not_to be_empty
- end
- end
- end
-
- describe '.cleanup' do
- it 'removes obsolete lookup entries' do
- Gitlab::Redis::SharedState.with do |redis|
- redis.set("session:user:gitlab:#{user.id}:6919a6f1bb119dd7396fadc38fd18d0d", '')
- redis.sadd("session:lookup:user:gitlab:#{user.id}", '6919a6f1bb119dd7396fadc38fd18d0d')
- redis.sadd("session:lookup:user:gitlab:#{user.id}", '59822c7d9fcdfa03725eff41782ad97d')
- end
-
- ActiveSession.cleanup(user)
-
- Gitlab::Redis::SharedState.with do |redis|
- expect(redis.smembers("session:lookup:user:gitlab:#{user.id}")).to eq ['6919a6f1bb119dd7396fadc38fd18d0d']
- end
- end
-
- it 'does not bail if there are no lookup entries' do
- ActiveSession.cleanup(user)
- end
- end
-end