diff --git a/lib/mozilla_iam/application_extensions.rb b/lib/mozilla_iam/application_extensions.rb index 74d61f2..21e3f72 100644 --- a/lib/mozilla_iam/application_extensions.rb +++ b/lib/mozilla_iam/application_extensions.rb @@ -2,13 +2,30 @@ module MozillaIAM module ApplicationExtensions def check_iam_session begin + return unless current_user + last_refresh = session[:mozilla_iam].try(:[], :last_refresh) + no_refresh = session[:mozilla_iam].try(:[], :no_refresh) + + return if no_refresh && !last_refresh + + unless last_refresh + current_user.clear_custom_fields + last_refresh = Profile.for(current_user)&.last_refresh + session[:mozilla_iam] = {} if session[:mozilla_iam].nil? + if last_refresh + session[:mozilla_iam][:last_refresh] = last_refresh + else + session[:mozilla_iam][:no_refresh] = true + return + end + end + logout_delay = Rails.cache.fetch('mozilla-iam/logout_delay') do ::PluginStore.get('mozilla-iam', 'logout_delay') end - return if last_refresh.nil? || !current_user if last_refresh + logout_delay < Time.now reset_session log_off_user diff --git a/lib/mozilla_iam/profile.rb b/lib/mozilla_iam/profile.rb index 3c70828..c6a2fa9 100644 --- a/lib/mozilla_iam/profile.rb +++ b/lib/mozilla_iam/profile.rb @@ -15,10 +15,15 @@ module MozillaIAM array_keys << key end - def refresh(user) + def for(user) uid = get(user, :uid) return if uid.blank? - Profile.new(user, uid).refresh + Profile.new(user, uid) + end + + def refresh(user) + profile = self.for(user) + profile.refresh unless profile.nil? end end @@ -56,8 +61,6 @@ module MozillaIAM return response end - private - def last_refresh @last_refresh ||= if time = get(:last_refresh) @@ -65,6 +68,8 @@ module MozillaIAM end end + private + def set_last_refresh(time) @last_refresh = set(:last_refresh, time) end diff --git a/plugin.rb b/plugin.rb index 69f3aa3..df0f2ad 100644 --- a/plugin.rb +++ b/plugin.rb @@ -1,6 +1,6 @@ # name: mozilla-iam # about: A plugin to integrate Discourse with Mozilla's Identity and Access Management (IAM) system -# version: 0.2.3 +# version: 0.2.4 # authors: Leo McArdle # url: https://github.com/mozilla/discourse-mozilla-iam diff --git a/spec/components/mozilla_iam/profile_spec.rb b/spec/components/mozilla_iam/profile_spec.rb index d540087..d52ab60 100644 --- a/spec/components/mozilla_iam/profile_spec.rb +++ b/spec/components/mozilla_iam/profile_spec.rb @@ -43,12 +43,26 @@ describe MozillaIAM::Profile do expect(result).to be true end - it 'should return nil if user has no profile' do + it 'returns nil if user has no profile' do result = MozillaIAM::Profile.refresh(user) expect(result).to be_nil end end + describe ".for" do + it "returns a user who has a profile" do + profile + MozillaIAM::Profile.expects(:new).with(user, "uid").returns(profile) + result = described_class.for(user) + expect(result).to eq profile + end + + it 'returns nil if user has no profile' do + result = described_class.for(user) + expect(result).to be_nil + end + end + context '#initialize' do it "should save a user's uid" do profile diff --git a/spec/controllers/application_controller_spec.rb b/spec/controllers/application_controller_spec.rb index 3574883..62f3752 100644 --- a/spec/controllers/application_controller_spec.rb +++ b/spec/controllers/application_controller_spec.rb @@ -9,6 +9,7 @@ describe TopicsController do last_refresh = Time.now - 14.minutes user.custom_fields['mozilla_iam_last_refresh'] = last_refresh + user.save_custom_fields session[:mozilla_iam] = { last_refresh: last_refresh } get :show, params: { id: 666 }, format: :json @@ -23,6 +24,7 @@ describe TopicsController do last_refresh = Time.now - 16.minutes user.custom_fields['mozilla_iam_last_refresh'] = last_refresh + user.save_custom_fields session[:mozilla_iam] = { last_refresh: last_refresh } get :show, params: { id: 666 }, format: :json @@ -36,6 +38,7 @@ describe TopicsController do last_refresh = Time.now - 8.days user.custom_fields['mozilla_iam_last_refresh'] = last_refresh + user.save_custom_fields session[:mozilla_iam] = { last_refresh: last_refresh } expect(session['current_user_id']).to be @@ -54,5 +57,82 @@ describe TopicsController do get :show, params: { id: 666 }, format: :json rescue expect(session['current_user_id']).to be_nil end + + context "with no session[:mozilla_iam] set" do + let(:user) { Fabricate(:user) } + before do + authenticate_user(user) + log_in_user(user) + session[:mozilla_iam] = nil + end + + context "and with a user with a last refresh" do + it "fetches last refresh from user profile" do + last_refresh = Time.now - 5.minutes + user.custom_fields['mozilla_iam_last_refresh'] = last_refresh + user.save_custom_fields + + get :show, params: { id: 666 }, format: :json + + expect(session[:mozilla_iam][:last_refresh]).to be_within(2.seconds).of last_refresh + end + end + + context "and with a user with no last refresh" do + it "sets session[:mozilla_iam][:no_refresh] to true" do + user.custom_fields['mozilla_iam_last_refresh'] = nil + user.save_custom_fields + + get :show, params: { id: 666 }, format: :json + + expect(session[:mozilla_iam][:no_refresh]).to eq true + end + end + + context "and with a user with no profile" do + it "sets session[:mozilla_iam][:no_refresh] to true" do + user.custom_fields['mozilla_iam_uid'] = nil + user.save_custom_fields + + get :show, params: { id: 666 }, format: :json + + expect(session[:mozilla_iam][:no_refresh]).to eq true + end + end + end + + context "with session[:mozilla_iam][:no_refresh] set to true" do + let(:user) { Fabricate(:user) } + before do + authenticate_user(user) + log_in_user(user) + session[:mozilla_iam] = { no_refresh: true } + end + + it "doesn't query user profile" do + MozillaIAM::Profile.expects(:for).never + + get :show, params: { id: 666 }, format: :json + end + + it "doesn't refresh user profile" do + MozillaIAM::Profile.expects(:refresh).never + + get :show, params: { id: 666 }, format: :json + end + + context "and with session[:mozilla_iam][:last_refresh] set" do + before do + last_refresh = Time.now - 5.minutes + session[:mozilla_iam][:last_refresh] = last_refresh + end + + it "refreshes user profile" do + MozillaIAM::Profile.expects(:refresh).once + + get :show, params: { id: 666 }, format: :json + end + end + end end end