Skip to content

Add support :routable_token option to add_authentication_token_field

What does this MR do and why?

This introduce a new :routable_token option to add_authentication_token_field to generate routable tokens.

This new option is available behind a :routable_token feature flag that can be set per user. Rollout issue: [Feature flag] Rollout of `routable_token` (#499537)

I took the opportunity to improve the existing tests and coverage and remove un-needed code in TokenAuthenticatable.

In !169322, we start using this option for PersonalAccessToken.

Steps to reproduce locally

  1. Checkout the branch which uses the :routable_token option in PersonalAccessToken (it builds upon this branch):
git fetch origin
git checkout -b '487009-add-routing-information-to-personal-access-tokens' 'origin/487009-add-routing-information-to-personal-access-tokens'
  1. Open a Rails console:
# Ensure the feature flag is disabled
> Feature.disable(:routable_token)

# Create a non-routable token
> pat1 = User.first.personal_access_tokens.create!(name: "My non-routable token", scopes: [:api], expires_at: 1.year.from_now)

# Check the token shape
> pat1.token
=> "glpat-ts8y8Mk2gxi-xvXVsxfN"

# Base-64 decode the payload, it doesn't contain routing information
> Base64.urlsafe_decode64(pat1.token.delete_prefix('glpat-'))
=> "\xB6\xCF2\xF0\xC96\x83\x18\xBE\xC6\xF5\xD5\xB3\x17\xCD"

# Enable the feature flag for User.first
> Feature.enable(:routable_token, User.first)

# Create a routable token
> pat2 = User.first.personal_access_tokens.create!(name: "My routable token", scopes: [:api], expires_at: 1.year.from_now)

# Check the token shape
> pat2.token
=> "glpat-cjoIsGd6XpA1Q1cldF88XbPFCnU6MQ"

# Base-64 decode the payload, it contains routing information
> Base64.urlsafe_decode64(pat2.token.delete_prefix('glpat-')).lines.map { |l| l.split(':') }.to_h
=> {"r"=>"\b\xB0gz^\x905CW%t_<]\xB3\xC5\n", "u"=>"1"}

# Enable the feature flag globally
> Feature.enable(:routable_token)

# Create another routable token
> pat3 = User.first.personal_access_tokens.create!(name: "My other routable token", scopes: [:api], expires_at: 1.year.from_now)

# Check the token shape
> pat3.token
=> "glpat-cjr0kB616GoXNbWWoxrI1aSgCnU6MQ"

# Base-64 decode the payload, it contains routing information
> Base64.urlsafe_decode64(pat3.token.delete_prefix('glpat-')).lines.map { |l| l.split(':') }.to_h
=> {"r"=>"\xF4\x90\x1E\xB5\xE8j\x175\xB5\x96\xA3\x1A\xC8\xD5\xA4\xA0\n", "u"=>"1"}

MR acceptance checklist

Please evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Related to #486946 (closed).

Edited by Rémy Coutable

Merge request reports

Loading