SECURITY: if last_refresh isn't set in session, fetch from user profile

This commit is contained in:
Leo McArdle 2018-08-29 18:56:54 +01:00
Родитель 2d0840d3cf
Коммит 672977ddf0
5 изменённых файлов: 123 добавлений и 7 удалений

Просмотреть файл

@ -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

Просмотреть файл

@ -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

Просмотреть файл

@ -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

Просмотреть файл

@ -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

Просмотреть файл

@ -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