Skip to content
Snippets Groups Projects
Unverified Commit 1ef5d4ae authored by Dylan Griffith's avatar Dylan Griffith Committed by Stan Hu
Browse files

Merge branch 'ia-token-logs-graphql' into 'master'

parent 76c25914
No related branches found
No related tags found
No related merge requests found
Loading
Loading
@@ -8,7 +8,7 @@ class Channel < ActionCable::Channel::Base
before_subscribe :validate_token_scope
 
def validate_token_scope
validate_access_token!(scopes: [:api, :read_api])
validate_and_save_access_token!(scopes: [:api, :read_api])
rescue Gitlab::Auth::InsufficientScopeError
reject
end
Loading
Loading
Loading
Loading
@@ -16,7 +16,6 @@ module Helpers
GITLAB_SHELL_JWT_ISSUER = "gitlab-shell"
SUDO_PARAM = :sudo
API_USER_ENV = 'gitlab.api.user'
API_TOKEN_ENV = 'gitlab.api.token'
API_EXCEPTION_ENV = 'gitlab.api.exception'
API_RESPONSE_STATUS_CODE = 'gitlab.api.response_status_code'
INTEGER_ID_REGEX = /^-?\d+$/
Loading
Loading
@@ -85,12 +84,10 @@ def current_user
 
sudo!
 
validate_access_token!(scopes: scopes_registered_for_endpoint) unless sudo?
validate_and_save_access_token!(scopes: scopes_registered_for_endpoint) unless sudo?
 
save_current_user_in_env(@current_user) if @current_user
 
save_current_token_in_env
if @current_user
load_balancer_stick_request(::ApplicationRecord, :user, @current_user.id)
end
Loading
Loading
@@ -103,13 +100,6 @@ def save_current_user_in_env(user)
env[API_USER_ENV] = { user_id: user.id, username: user.username }
end
 
def save_current_token_in_env
token = access_token
env[API_TOKEN_ENV] = { token_id: token.id, token_type: token.class } if token
rescue Gitlab::Auth::UnauthorizedError
end
def sudo?
initial_current_user != current_user
end
Loading
Loading
@@ -820,7 +810,7 @@ def sudo!
forbidden!('Must be authenticated using an OAuth or Personal Access Token to use sudo')
end
 
validate_access_token!(scopes: [:sudo])
validate_and_save_access_token!(scopes: [:sudo])
 
sudoed_user = find_user(sudo_identifier)
not_found!("User with ID or username '#{sudo_identifier}'") unless sudoed_user
Loading
Loading
Loading
Loading
@@ -100,7 +100,7 @@ def retrieve_user_from_session_cookie
def retrieve_user_from_personal_access_token
return unless access_token.present?
 
validate_access_token!(scopes: [Gitlab::Auth::K8S_PROXY_SCOPE])
validate_and_save_access_token!(scopes: [Gitlab::Auth::K8S_PROXY_SCOPE])
 
::PersonalAccessTokens::LastUsedService.new(access_token).execute
 
Loading
Loading
Loading
Loading
@@ -23,6 +23,7 @@ module AuthFinders
include ActionController::HttpAuthentication::Basic
include ActionController::HttpAuthentication::Token
 
API_TOKEN_ENV = 'gitlab.api.token'
PRIVATE_TOKEN_HEADER = 'HTTP_PRIVATE_TOKEN'
PRIVATE_TOKEN_PARAM = :private_token
JOB_TOKEN_HEADER = 'HTTP_JOB_TOKEN'
Loading
Loading
@@ -123,7 +124,7 @@ def find_user_from_lfs_token
def find_user_from_personal_access_token
return unless access_token
 
validate_access_token!
validate_and_save_access_token!
 
access_token&.user || raise(UnauthorizedError)
end
Loading
Loading
@@ -137,7 +138,7 @@ def find_user_from_personal_access_token
def find_user_from_web_access_token(request_format, scopes: [:api])
return unless access_token && valid_web_access_format?(request_format)
 
validate_access_token!(scopes: scopes)
validate_and_save_access_token!(scopes: scopes)
 
::PersonalAccessTokens::LastUsedService.new(access_token).execute
 
Loading
Loading
@@ -147,7 +148,7 @@ def find_user_from_web_access_token(request_format, scopes: [:api])
def find_user_from_access_token
return unless access_token
 
validate_access_token!
validate_and_save_access_token!
 
::PersonalAccessTokens::LastUsedService.new(access_token).execute
 
Loading
Loading
@@ -192,7 +193,7 @@ def find_runner_from_token
::Ci::Runner.find_by_token(token) || raise(UnauthorizedError)
end
 
def validate_access_token!(scopes: [])
def validate_and_save_access_token!(scopes: [])
# return early if we've already authenticated via a job token
return if @current_authenticated_job.present? # rubocop:disable Gitlab/ModuleWithInstanceVariables
 
Loading
Loading
@@ -213,6 +214,8 @@ def validate_access_token!(scopes: [])
when AccessTokenValidationService::IMPERSONATION_DISABLED
raise ImpersonationDisabled
end
save_current_token_in_env
end
 
def authentication_token_present?
Loading
Loading
@@ -223,6 +226,10 @@ def authentication_token_present?
 
private
 
def save_current_token_in_env
request.env[API_TOKEN_ENV] = { token_id: access_token.id, token_type: access_token.class.to_s }
end
def find_user_from_job_bearer_token
return unless route_authentication_setting[:job_token_allowed]
 
Loading
Loading
Loading
Loading
@@ -70,7 +70,7 @@ def find_user_from_personal_access_token_for_api_or_git
end
 
def valid_access_token?(scopes: [])
validate_access_token!(scopes: scopes)
validate_and_save_access_token!(scopes: scopes)
 
true
rescue Gitlab::Auth::AuthenticationError
Loading
Loading
Loading
Loading
@@ -5,7 +5,7 @@ module GrapeLogging
module Loggers
class TokenLogger < ::GrapeLogging::Loggers::Base
def parameters(request, _)
params = request.env[::API::Helpers::API_TOKEN_ENV]
params = request.env[::Gitlab::Auth::AuthFinders::API_TOKEN_ENV]
 
return {} unless params
 
Loading
Loading
Loading
Loading
@@ -40,6 +40,9 @@ def log_execute_query(query: nil, duration_s: 0, exception: nil)
query_string: query.query_string
}
 
token_info = auth_token_info(query)
info.merge!(token_info) if token_info
Gitlab::ExceptionLogFormatter.format!(exception, info)
 
info.merge!(::Gitlab::ApplicationContext.current)
Loading
Loading
@@ -48,6 +51,13 @@ def log_execute_query(query: nil, duration_s: 0, exception: nil)
::Gitlab::GraphqlLogger.info(info)
end
 
def auth_token_info(query)
request_env = query.context[:request]&.env
return unless request_env
request_env[::Gitlab::Auth::AuthFinders::API_TOKEN_ENV]
end
def clean_variables(variables)
filtered = ActiveSupport::ParameterFilter
.new(::Rails.application.config.filter_parameters)
Loading
Loading
Loading
Loading
@@ -921,7 +921,7 @@ def auth_header_with(token)
end
 
describe '#validate_access_token!' do
subject { validate_access_token! }
subject { validate_and_save_access_token! }
 
context 'with a job token' do
let(:route_authentication_setting) { { job_token_allowed: true } }
Loading
Loading
@@ -937,30 +937,41 @@ def auth_header_with(token)
end
 
it 'returns nil if no access_token present' do
expect(validate_access_token!).to be_nil
expect(validate_and_save_access_token!).to be_nil
end
 
context 'token is not valid' do
context 'with a personal access token' do
let_it_be_with_reload(:personal_access_token) { create(:personal_access_token, user: user) }
 
before do
allow_any_instance_of(described_class).to receive(:access_token).and_return(personal_access_token)
end
 
it 'returns Gitlab::Auth::ExpiredError if token expired' do
personal_access_token.update!(expires_at: 1.day.ago)
it 'saves the token info in the environment' do
subject
 
expect { validate_access_token! }.to raise_error(Gitlab::Auth::ExpiredError)
expect(request.env).to have_key(described_class::API_TOKEN_ENV)
end
 
it 'returns Gitlab::Auth::RevokedError if token revoked' do
personal_access_token.revoke!
context 'when the token is not valid' do
it 'returns Gitlab::Auth::ExpiredError if token expired', :aggregate_failures do
personal_access_token.update!(expires_at: 1.day.ago)
 
expect { validate_access_token! }.to raise_error(Gitlab::Auth::RevokedError)
end
expect { validate_and_save_access_token! }.to raise_error(Gitlab::Auth::ExpiredError)
expect(request.env).not_to have_key(described_class::API_TOKEN_ENV)
end
it 'returns Gitlab::Auth::RevokedError if token revoked', :aggregate_failures do
personal_access_token.revoke!
 
it 'returns Gitlab::Auth::InsufficientScopeError if invalid token scope' do
expect { validate_access_token!(scopes: [:sudo]) }.to raise_error(Gitlab::Auth::InsufficientScopeError)
expect { validate_and_save_access_token! }.to raise_error(Gitlab::Auth::RevokedError)
expect(request.env).not_to have_key(described_class::API_TOKEN_ENV)
end
it 'returns Gitlab::Auth::InsufficientScopeError if invalid token scope', :aggregate_failures do
expect { validate_and_save_access_token!(scopes: [:sudo]) }.to raise_error(Gitlab::Auth::InsufficientScopeError)
expect(request.env).not_to have_key(described_class::API_TOKEN_ENV)
end
end
end
 
Loading
Loading
@@ -974,7 +985,7 @@ def auth_header_with(token)
end
 
it 'returns Gitlab::Auth::ImpersonationDisabled' do
expect { validate_access_token! }.to raise_error(Gitlab::Auth::ImpersonationDisabled)
expect { validate_and_save_access_token! }.to raise_error(Gitlab::Auth::ImpersonationDisabled)
end
end
end
Loading
Loading
Loading
Loading
@@ -59,4 +59,19 @@
 
expect { dummy_schema.execute(query_string) }.to raise_error(/This field is supposed to break/)
end
it 'logs token details on authenticated requests', :aggregate_failures do
variables = { name: "Ada Lovelace" }
query_string = 'query fooOperation($name: String) { helloWorld(message: $name) }'
mock_token_info = { token_type: "PersonalAccessToken", token_id: "12345" }
mock_request_env = { ::Gitlab::Auth::AuthFinders::API_TOKEN_ENV => mock_token_info }
mock_request = instance_double(ActionDispatch::Request, env: mock_request_env)
context = { request: mock_request }
expect(::Gitlab::GraphqlLogger).to receive(:info).with(hash_including({
token_type: mock_token_info[:token_type],
token_id: mock_token_info[:token_id]
}))
dummy_schema.execute(query_string, variables: variables, context: context)
end
end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment