Commit 34ec29b9 authored by Kamil Trzciński's avatar Kamil Trzciński

Support multiple scopes when using authing container registry scopes

parent 3d2dad44
...@@ -54,6 +54,22 @@ class JwtController < ApplicationController ...@@ -54,6 +54,22 @@ class JwtController < ApplicationController
end end
def auth_params def auth_params
params.permit(:service, :scope, :account, :client_id) params.permit(:service, :account, :client_id)
.merge(additional_params)
end
def additional_params
{ scopes: scopes_param }.compact
end
# We have to parse scope here, because Docker Client does not send an array of scopes,
# but rather a flat list and we loose second scope when being processed by Rails:
# scope=scopeA&scope=scopeB
#
# This method makes to always return an array of scopes
def scopes_param
return unless params[:scope].present?
Array(Rack::Utils.parse_query(request.query_string)['scope'])
end end
end end
...@@ -9,11 +9,11 @@ module Auth ...@@ -9,11 +9,11 @@ module Auth
return error('UNAVAILABLE', status: 404, message: 'registry not enabled') unless registry.enabled return error('UNAVAILABLE', status: 404, message: 'registry not enabled') unless registry.enabled
unless scope || current_user || project unless scopes.any? || current_user || project
return error('DENIED', status: 403, message: 'access forbidden') return error('DENIED', status: 403, message: 'access forbidden')
end end
{ token: authorized_token(scope).encoded } { token: authorized_token(*scopes).encoded }
end end
def self.full_access_token(*names) def self.full_access_token(*names)
...@@ -47,10 +47,12 @@ module Auth ...@@ -47,10 +47,12 @@ module Auth
end end
end end
def scope def scopes
return unless params[:scope] return [] unless params[:scopes]
@scope ||= process_scope(params[:scope]) @scopes ||= params[:scopes].map do |scope|
process_scope(scope)
end.compact
end end
def process_scope(scope) def process_scope(scope)
......
---
title: Support multiple scopes when authing container registry scopes
merge_request: 20617
author:
type: fixed
...@@ -70,6 +70,25 @@ describe JwtController do ...@@ -70,6 +70,25 @@ describe JwtController do
it { expect(service_class).to have_received(:new).with(nil, user, parameters) } it { expect(service_class).to have_received(:new).with(nil, user, parameters) }
context 'when passing a flat array of scopes' do
# We use this trick to make rails to generate a query_string:
# scope=scope1&scope=scope2
# It works because :scope and 'scope' are the same as string, but different objects
let(:parameters) do
{
:service => service_name,
:scope => 'scope1',
'scope' => 'scope2'
}
end
let(:service_parameters) do
{ service: service_name, scopes: %w(scope1 scope2) }
end
it { expect(service_class).to have_received(:new).with(nil, user, service_parameters) }
end
context 'when user has 2FA enabled' do context 'when user has 2FA enabled' do
let(:user) { create(:user, :two_factor) } let(:user) { create(:user, :two_factor) }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment