Browse Source

Fixes #2266 - Login always redirected to dashboard after third party / OAuth2 login (e.g. Google)

Martin Edenhofer 4 years ago
parent
commit
c505851e4c

+ 21 - 6
app/assets/javascripts/app/controllers/_application_controller/_base.coffee

@@ -234,9 +234,7 @@ class App.Controller extends Spine.Controller
     return true if @permissionCheck(key)
 
     # remember requested url
-    location = window.location.hash
-    if location && location isnt '#login' && location isnt '#logout' && location isnt '#keyboard_shortcuts'
-      App.Config.set('requested_url', location)
+    @requestedUrlToStore()
 
     if closeTab
       App.TaskManager.remove(@taskKey)
@@ -255,9 +253,7 @@ class App.Controller extends Spine.Controller
     return true if @authenticateCheck()
 
     # remember requested url
-    location = window.location.hash
-    if location && location isnt '#login' && location isnt '#logout' && location isnt '#keyboard_shortcuts'
-      @Config.set('requested_url', location)
+    @requestedUrlToStore()
 
     # redirect to login
     @navigate '#login'
@@ -271,6 +267,25 @@ class App.Controller extends Spine.Controller
     return true if @Session.get()
     false
 
+  requestedUrlToStore: ->
+    location = window.location.hash
+
+    return if !location
+    return if location is '#'
+    return if location is '#login'
+    return if location is '#logout'
+    return if location is '#keyboard_shortcuts'
+
+    # remember requested url
+    @requestedUrlRemember(location)
+
+  requestedUrlRemember: (location) ->
+    App.SessionStorage.set('requested_url', location) # for authentication agains third party
+    App.Config.set('requested_url', location) # for local re-login
+
+  requestedUrlWas: ->
+    App.SessionStorage.get('requested_url') || App.Config.get('requested_url')
+
   frontendTimeUpdate: =>
     update = =>
       @frontendTimeUpdateElement($('#app'))

+ 8 - 0
app/assets/javascripts/app/controllers/default_route.coffee

@@ -17,6 +17,14 @@ class DefaultRouter extends App.Controller
       @navigate '#getting_started', { hideCurrentLocationFromHistory: true }
       return
 
+    # redirect to requested url
+    requested_url = @requestedUrlWas()
+    if requested_url
+      @requestedUrlRemember('')
+      @log 'notice', "REDIRECT to '#{requested_url}'"
+      @navigate requested_url, { hideCurrentLocationFromHistory: true }
+      return
+
     if @Config.get('default_controller')
       @navigate @Config.get('default_controller'), { hideCurrentLocationFromHistory: true }
       return

+ 2 - 10
app/assets/javascripts/app/controllers/login.coffee

@@ -79,16 +79,8 @@ class Login extends App.ControllerFullPage
     App.Plugin.init()
 
     # redirect to #
-    requested_url = @Config.get('requested_url')
-    if requested_url && requested_url isnt '#login' && requested_url isnt '#logout'
-      @log 'notice', "REDIRECT to '#{requested_url}'"
-      @navigate requested_url
-
-      # reset
-      @Config.set('requested_url', '')
-    else
-      @log 'notice', 'REDIRECT to -#/-'
-      @navigate '#/'
+    @log 'notice', 'REDIRECT to -#/-'
+    @navigate '#/'
 
   error: (xhr, statusText, error) =>
     detailsRaw = xhr.responseText

+ 37 - 0
spec/system/basic/authentication_spec.rb

@@ -25,4 +25,41 @@ RSpec.describe 'Authentication', type: :system do
     # check wrong displayed fields in registration form after logout. #2989
     expect(page).to have_no_selector('select[name=organization_id]')
   end
+
+  it 'Login and redirect to requested url', authenticated_as: false do
+    visit 'ticket/zoom/1'
+
+    expect_current_route 'login', wait: 2
+
+    login(
+      username: 'master@example.com',
+      password: 'test',
+    )
+
+    expect_current_route 'ticket/zoom/1', wait: 2
+  end
+
+  it 'Login and redirect to requested url via external authentication', authenticated_as: false do
+    visit 'ticket/zoom/1'
+
+    expect_current_route 'login', wait: 2
+
+    # simulate jump to external ressource
+    visit 'https://www.zammad.org'
+
+    # simulate successful login via third party
+    user = User.find_by(login: 'master@example.com')
+    ActiveRecord::SessionStore::Session.all.each do |session|
+      session.data[:user_id] = user.id
+      session.save!
+    end
+
+    # jump back and check if origin requested url is shown
+    visit ''
+
+    expect_current_route 'ticket/zoom/1', wait: 2
+
+    expect(current_login).to eq('master@example.com')
+  end
+
 end