From 5b8715184ea83945bba2783ffcf09e0db14a1565 Mon Sep 17 00:00:00 2001 From: Martin Edenhofer Date: Sun, 24 Sep 2017 23:51:55 +0200 Subject: [PATCH] Fixed issue #1280 - Invalidate cache when switching users. --- .../_application_controller_generic.coffee | 5 +- .../app/lib/app_init/session.coffee | 10 +-- .../app/lib/app_post/_collection_base.coffee | 7 ++ .../javascripts/app/lib/app_post/auth.coffee | 33 ++++---- .../app_post/overview_list_collection.coffee | 9 ++ .../app/models/_application_model.coffee | 26 ++++++ script/build/test_slice_tests.sh | 6 ++ test/browser/user_switch_cache_test.rb | 83 +++++++++++++++++++ 8 files changed, 158 insertions(+), 21 deletions(-) create mode 100644 test/browser/user_switch_cache_test.rb diff --git a/app/assets/javascripts/app/controllers/_application_controller_generic.coffee b/app/assets/javascripts/app/controllers/_application_controller_generic.coffee index f764e5c57..71789f94c 100644 --- a/app/assets/javascripts/app/controllers/_application_controller_generic.coffee +++ b/app/assets/javascripts/app/controllers/_application_controller_generic.coffee @@ -1162,7 +1162,7 @@ class App.ObserverController extends App.Controller @log 'debug', 'new', @object_id, @model if App[@model].exists(@object_id) - @maybeRender( App[@model].fullLocal(@object_id) ) + @maybeRender(App[@model].fullLocal(@object_id)) else App[@model].full(@object_id, @maybeRender) @@ -1170,7 +1170,8 @@ class App.ObserverController extends App.Controller if @globalRerender @bind('ui:rerender', => @lastAttributres = undefined - @maybeRender( App[@model].fullLocal(@object_id) ) + console.log('aaaa', @model, @template) + @maybeRender(App[@model].fullLocal(@object_id)) ) subscribe: (object, typeOfChange) => diff --git a/app/assets/javascripts/app/lib/app_init/session.coffee b/app/assets/javascripts/app/lib/app_init/session.coffee index 2a670e8d7..87bf31d2d 100644 --- a/app/assets/javascripts/app/lib/app_init/session.coffee +++ b/app/assets/javascripts/app/lib/app_init/session.coffee @@ -5,12 +5,12 @@ class App.Session _instance ?= new _sessionSingleton _instance.clear() - @get: ( key ) -> + @get: (key) -> if _instance == undefined _instance ?= new _sessionSingleton _instance.get(key) - @set: ( user ) -> + @set: (user) -> if _instance == undefined _instance ?= new _sessionSingleton _instance.set(user) @@ -24,11 +24,11 @@ class _sessionSingleton extends Spine.Module clear: -> @user = undefined - get: ( key ) -> + get: (key) -> return if !@user if key return @user[key] @user - set: ( user ) -> - @user = user \ No newline at end of file + set: (user) -> + @user = user diff --git a/app/assets/javascripts/app/lib/app_post/_collection_base.coffee b/app/assets/javascripts/app/lib/app_post/_collection_base.coffee index d031dfa11..ddd758914 100644 --- a/app/assets/javascripts/app/lib/app_post/_collection_base.coffee +++ b/app/assets/javascripts/app/lib/app_post/_collection_base.coffee @@ -6,6 +6,7 @@ class App._CollectionSingletonBase @callbacks = {} @counter = 0 @key = "collection-#{@event}" + # read from cache cache = App.SessionStorage.get(@key) if cache @@ -16,6 +17,9 @@ class App._CollectionSingletonBase @set(data) @callback(data) + App.Event.bind 'auth:logout', (data) => + @clear(data) + get: => @collectionData @@ -79,3 +83,6 @@ class App._CollectionSingletonBase delete @callbacks[counter] App.QueueManager.add(@key, callback) App.QueueManager.run(@key) + + clear: => + @collectionData = undefined diff --git a/app/assets/javascripts/app/lib/app_post/auth.coffee b/app/assets/javascripts/app/lib/app_post/auth.coffee index fe364474c..f46c8c6e3 100644 --- a/app/assets/javascripts/app/lib/app_post/auth.coffee +++ b/app/assets/javascripts/app/lib/app_post/auth.coffee @@ -76,13 +76,7 @@ class App.Auth App.Session.init() # update model definition (needed for not authenticated areas like wizard) - if data.models - for model, attributes of data.models - if !App[model] - throw "No such model App.#{model}" - for attribute in attributes - App[model].attributes.push attribute.name - App[model].configure_attributes.push attribute + @_updateModelAttributes(data.models) # set locale locale = window.navigator.userLanguage || window.navigator.language || 'en-us' @@ -100,13 +94,7 @@ class App.Auth App.Event.trigger('clearStore') # update model definition - if data.models - for model, attributes of data.models - if !App[model] - throw "No such model App.#{model}" - for attribute in attributes - App[model].attributes.push attribute.name - App[model].configure_attributes.push attribute + @_updateModelAttributes(data.models) # update config for key, value of data.config @@ -139,6 +127,14 @@ class App.Auth App.Event.trigger('ui:rerender') App.TaskManager.tasksInitial() + @_updateModelAttributes: (models) -> + return if _.isEmpty(models) + + for model, attributes of models + if App[model] + if _.isFunction(App[model].updateAttributes) + App[model].updateAttributes(attributes) + @_logout: (rerender = true) -> App.Log.debug 'Auth', '_logout' @@ -153,6 +149,15 @@ class App.Auth App.Event.trigger('ui:rerender') App.Event.trigger('clearStore') + # clear all in-memory data of all App.Model's + for model_key, model_object of App + if _.isFunction(model_object.resetCallbacks) + model_object.resetCallbacks() + if _.isFunction(model_object.resetAttributes) + model_object.resetAttributes() + if _.isFunction(model_object.clearInMemory) + model_object.clearInMemory() + @_loginError: -> App.Log.debug 'Auth', '_loginError:error' diff --git a/app/assets/javascripts/app/lib/app_post/overview_list_collection.coffee b/app/assets/javascripts/app/lib/app_post/overview_list_collection.coffee index b605f5503..871f8b660 100644 --- a/app/assets/javascripts/app/lib/app_post/overview_list_collection.coffee +++ b/app/assets/javascripts/app/lib/app_post/overview_list_collection.coffee @@ -14,6 +14,9 @@ class _Singleton @overview[data.overview.view] = data @callback(data.overview.view, data) + App.Event.bind 'auth:logout', (data) => + @clear(data) + get: (view) -> @overview[view] @@ -76,6 +79,12 @@ class _Singleton App.QueueManager.add('ticket_overviews', callback) App.QueueManager.run('ticket_overviews') + clear: => + @overview = {} + @callbacks = {} + @fetchActive = {} + @counter = 0 + class App.OverviewListCollection _instance = new _Singleton diff --git a/app/assets/javascripts/app/models/_application_model.coffee b/app/assets/javascripts/app/models/_application_model.coffee index 49ad8aac9..b6a3e62ce 100644 --- a/app/assets/javascripts/app/models/_application_model.coffee +++ b/app/assets/javascripts/app/models/_application_model.coffee @@ -812,3 +812,29 @@ set new attributes of model (remove already available attributes) item: item processData: true ) + + @clearInMemory: -> + return if !@className + + # reset attributes to prevent cached forms on relogin + if !_.isEmpty(App[@className].org_configure_attributes) + App[@className].configure_attributes = App[@className].org_configure_attributes + + # reset cached values of model + App[@className].deleteAll() + + @updateAttributes: (attributes) -> + return if !@className + if _.isEmpty(@org_configure_attributes) + @org_configure_attributes = clone(@configure_attributes) + for attribute in attributes + @attributes.push attribute.name + @configure_attributes.push attribute + + @resetAttributes: -> + return if _.isEmpty(@org_configure_attributes) + @configure_attributes = @org_configure_attributes + + @resetCallbacks: -> + @SUBSCRIPTION_ITEM = {} + @SUBSCRIPTION_COLLECTION = {} diff --git a/script/build/test_slice_tests.sh b/script/build/test_slice_tests.sh index 00f5b7e2f..34e837538 100755 --- a/script/build/test_slice_tests.sh +++ b/script/build/test_slice_tests.sh @@ -60,6 +60,7 @@ if [ "$LEVEL" == '1' ]; then # test/browser/taskbar_session_test.rb # test/browser/taskbar_task_test.rb # test/browser/translation_test.rb + rm test/browser/user_switch_cache_test.rb elif [ "$LEVEL" == '2' ]; then echo "slicing level 2" @@ -117,6 +118,7 @@ elif [ "$LEVEL" == '2' ]; then rm test/browser/taskbar_session_test.rb rm test/browser/taskbar_task_test.rb rm test/browser/translation_test.rb + #rm test/browser/user_switch_cache_test.rb elif [ "$LEVEL" == '3' ]; then echo "slicing level 3" @@ -174,6 +176,7 @@ elif [ "$LEVEL" == '3' ]; then rm test/browser/taskbar_session_test.rb rm test/browser/taskbar_task_test.rb rm test/browser/translation_test.rb + rm test/browser/user_switch_cache_test.rb elif [ "$LEVEL" == '4' ]; then echo "slicing level 4" @@ -231,6 +234,7 @@ elif [ "$LEVEL" == '4' ]; then rm test/browser/taskbar_session_test.rb rm test/browser/taskbar_task_test.rb rm test/browser/translation_test.rb + rm test/browser/user_switch_cache_test.rb elif [ "$LEVEL" == '5' ]; then echo "slicing level 5" @@ -287,6 +291,7 @@ elif [ "$LEVEL" == '5' ]; then rm test/browser/taskbar_session_test.rb rm test/browser/taskbar_task_test.rb rm test/browser/translation_test.rb + rm test/browser/user_switch_cache_test.rb elif [ "$LEVEL" == '6' ]; then echo "slicing level 6" @@ -346,6 +351,7 @@ elif [ "$LEVEL" == '6' ]; then rm test/browser/taskbar_session_test.rb rm test/browser/taskbar_task_test.rb rm test/browser/translation_test.rb + rm test/browser/user_switch_cache_test.rb else echo "ERROR: Invalid level $LEVEL - 1, 2, 3, 4, 5 or 6 is available" diff --git a/test/browser/user_switch_cache_test.rb b/test/browser/user_switch_cache_test.rb new file mode 100644 index 000000000..7b700c7ab --- /dev/null +++ b/test/browser/user_switch_cache_test.rb @@ -0,0 +1,83 @@ +# encoding: utf-8 +require 'browser_test_helper' + +class UserSwitchCache < TestCase + def test_re_login + + # login as agent and create one ticket + @browser = browser_instance + login( + username: 'agent1@example.com', + password: 'test', + url: browser_url, + ) + tasks_close_all() + ticket1 = ticket_create( + data: { + customer: 'nico', + group: 'Users', + title: 'some subject 123äöü - reply test', + body: 'some body 123äöü - reply test', + }, + ) + + logout() + + # login as customer and verify ticket create screen + login( + username: 'nicole.braun@zammad.org', + password: 'test', + url: browser_url, + ) + click(css: 'a[href="#new"]') + click(css: 'a[href="#customer_ticket_new"]') + sleep 4 + + match( + css: '#content', + value: 'Priority', + should_not_match: true, + ) + + match( + css: '#content', + value: 'Owner', + should_not_match: true, + ) + + match( + css: '#content', + value: 'State', + ) + + logout() + + # login again as customer and verify ticket create screen + login( + username: 'nicole.braun@zammad.org', + password: 'test', + url: browser_url, + ) + click(css: 'a[href="#new"]') + click(css: 'a[href="#customer_ticket_new"]') + sleep 4 + + match( + css: '#content', + value: 'Priority', + should_not_match: true, + ) + + match( + css: '#content', + value: 'Owner', + should_not_match: true, + ) + + match( + css: '#content', + value: 'State', + ) + + end +end