allow configuring token expiration for mobile apps

fixes FOO-2336

Change-Id: Ic7f555ae4d85b8b79c7114f43495a638ca2dead2
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/273587
Reviewed-by: Simon Williams <simon@instructure.com>
Reviewed-by: August Thornton <august@instructure.com>
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
QA-Review: Cody Cutrer <cody@instructure.com>
Product-Review: Cody Cutrer <cody@instructure.com>
This commit is contained in:
Cody Cutrer 2021-09-14 16:26:41 -06:00
parent 1ddbd02b3a
commit 3ef09eed34
5 changed files with 42 additions and 5 deletions

View File

@ -345,6 +345,17 @@ class DeveloperKey < ActiveRecord::Base
end end
end end
def mobile_app?
false
end
def tokens_expire_in
return nil unless mobile_app?
sessions_settings = Canvas::Plugin.find('sessions').settings || {}
sessions_settings[:mobile_timeout]&.to_f&.minutes
end
private private
def validate_lti_fields def validate_lti_fields

View File

@ -22,5 +22,9 @@
<td><%= f.blabel :session_timeout, :en => "Time before session expires in minutes (20 minimum)" %></td> <td><%= f.blabel :session_timeout, :en => "Time before session expires in minutes (20 minimum)" %></td>
<td><%= f.text_field :session_timeout %></td> <td><%= f.text_field :session_timeout %></td>
</tr> </tr>
<tr>
<td><%= f.blabel :mobile_timeout, :en => "Time before session expires in minutes (20 minimum) for mobile applications" %></td>
<td><%= f.text_field :mobile_timeout %></td>
</tr>
</table> </table>
<% end %> <% end %>

View File

@ -94,6 +94,9 @@ module Canvas::Oauth
}) })
@access_token.real_user = real_user if real_user && real_user != user @access_token.real_user = real_user if real_user && real_user != user
expires_in = key.tokens_expire_in
@access_token.permanent_expires_at = Time.now.utc + expires_in if expires_in
@access_token.save! @access_token.save!
@access_token.clear_full_token! if @access_token.scoped_to?(['userinfo']) @access_token.clear_full_token! if @access_token.scoped_to?(['userinfo'])

View File

@ -20,11 +20,23 @@
module Canvas::Plugins::Validators::SessionsValidator module Canvas::Plugins::Validators::SessionsValidator
def self.validate(settings, plugin_setting) def self.validate(settings, plugin_setting)
timeout = settings["session_timeout"].to_f.minutes settings_keys = %w[session_timeout mobile_timeout]
if timeout.to_i < 20.minutes.to_i result = {}
plugin_setting.errors.add(:base, I18n.t('canvas.plugins.errors.login_expiration_minimum', 'Session expiration must be 20 minutes or greater')) settings_keys.each do |key|
else if settings[key].blank?
settings.to_hash.with_indifferent_access result[key] = nil
next
end end
timeout = settings[key].to_f.minutes
if timeout.to_i < 20.minutes.to_i
plugin_setting.errors.add(:base, I18n.t('canvas.plugins.errors.login_expiration_minimum',
'Session expiration must be 20 minutes or greater'))
end
result[key] = timeout.to_i / 60
end
return unless plugin_setting.errors.empty?
result.with_indifferent_access
end end
end end

View File

@ -94,6 +94,7 @@ module Canvas::Oauth
expect(token.access_token).to be_a AccessToken expect(token.access_token).to be_a AccessToken
expect(user.access_tokens.reload.size).to eq 1 expect(user.access_tokens.reload.size).to eq 1
expect(token.access_token.full_token).not_to be_empty expect(token.access_token.full_token).not_to be_empty
expect(token.access_token.permanent_expires_at).to be_nil
end end
it 'creates a scoped access token' do it 'creates a scoped access token' do
@ -135,6 +136,12 @@ module Canvas::Oauth
expect(token.access_token).to be_a AccessToken expect(token.access_token).to be_a AccessToken
expect(token.access_token).not_to eq access_token expect(token.access_token).not_to eq access_token
end end
it 'sets token to expire if the key is set to expire' do
allow(key).to receive(:mobile_app?).and_return(true)
allow(Canvas::Plugin).to receive(:find).with("sessions").and_return(double(settings: { mobile_timeout: 30 }))
expect(token.access_token.permanent_expires_at).not_to be_nil
end
end end
describe '#create_access_token_if_needed' do describe '#create_access_token_if_needed' do