Skip to content

Commit

Permalink
Set new admin token only if REMOTE_USER is set
Browse files Browse the repository at this point in the history
  • Loading branch information
codez committed Nov 11, 2022
1 parent 5831a70 commit 5884ac4
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 14 deletions.
14 changes: 10 additions & 4 deletions app/controllers/auth/remote_header.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,16 @@ class RemoteHeader < Base
REMOTE_USER_GROUPS
REMOTE_USER_FIRST_NAME
REMOTE_USER_LAST_NAME
]
].freeze

def fetch_user
fetch_user_and_update_user(*remote_user_params)
end

def present?
header(REMOTE_USER_HEADERS.first).present?
end

private

def fetch_user_and_update_user(username, groups, first_name, last_name)
Expand All @@ -31,12 +35,14 @@ def fetch_user_and_update_user(username, groups, first_name, last_name)
end

def remote_user_params
h = request.headers
REMOTE_USER_HEADERS.map do |key|
str = h[key] || h[key.gsub('_', '-')]
str&.force_encoding('UTF-8')
header(key)&.force_encoding('UTF-8')
end
end

def header(key)
request.headers[key] || request.headers[key.tr('_', '-')]
end

end
end
6 changes: 5 additions & 1 deletion app/controllers/login_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,26 +47,28 @@ class LoginController < ApplicationController

def show
set_user_from_any_auth
generate_admin_token if Auth::RemoteHeader.new(request).present?
render_current_user
end

# POST /login: Placeholder login action to act as FreeIPA endpoint.
def create
set_user_from_remote_header
generate_admin_token
render_current_user
end

def update
set_user_from_remote_header
current_user&.regenerate_api_key!
generate_admin_token
render_current_user
end

private

def render_current_user
if current_user
generate_admin_token if current_user.admin?
render json: current_user, serializer: UserSerializer
else
render json: { errors: request.headers['EXTERNAL_AUTH_ERROR'] || 'Not authenticated' },
Expand All @@ -75,6 +77,8 @@ def render_current_user
end

def generate_admin_token
return unless current_user&.admin?

headers['X-Auth-Token'] = Auth::Jwt.generate_token(current_user)
end

Expand Down
2 changes: 2 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
get 'login', to: 'login#show'
post 'login', to: 'login#create'
patch 'login', to: 'login#update'
# duplicate entry to allow different server config for checking sso authentication
get 'sso', to: 'login#show'

get 'status', to: 'status#show'

Expand Down
16 changes: 9 additions & 7 deletions test/controllers/auth/remote_header_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,15 @@ class RemoteHeaderTest < ActiveSupport::TestCase
private

def fetch_user(username, groups, first_name, last_name)
request = stub('request')
request.expects(headers: {
'REMOTE_USER' => username,
'REMOTE_USER_GROUPS' => groups,
'REMOTE_USER_FIRST_NAME' => first_name,
'REMOTE_USER_LAST_NAME' => last_name
})
request = stub(
'request',
headers: {
'REMOTE_USER' => username,
'REMOTE_USER_GROUPS' => groups,
'REMOTE_USER_FIRST_NAME' => first_name,
'REMOTE_USER_LAST_NAME' => last_name
}
)
Auth::RemoteHeader.new(request).fetch_user
end

Expand Down
34 changes: 32 additions & 2 deletions test/controllers/login_controller_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,17 @@ class LoginControllerTest < ActionController::TestCase
assert_equal 'speedee', json['data']['attributes']['username']
assert_match /\A#{users(:speedee).id}\$[A-Za-z0-9]{24}\z/,
json['data']['attributes']['api_token']
assert response.headers['X-Auth-Token'].blank?
end

test 'GET show with REMOTE_USER returns admin user object and jwt' do
request.env['REMOTE_USER'] = +'admin'
get :show
assert_response 200
assert_equal 'admin', json['data']['attributes']['username']
assert_match /\A#{users(:admin).id}\$[A-Za-z0-9]{24}\z/,
json['data']['attributes']['api_token']
assert response.headers['X-Auth-Token'].present?
end

test 'GET show with api_token returns user object' do
Expand All @@ -20,6 +31,14 @@ class LoginControllerTest < ActionController::TestCase
assert_equal 'speedee', json['data']['attributes']['username']
end

test 'GET show with api_token returns admin user object but no JWT' do
get :show,
params: { api_token: users(:admin).api_token }
assert_response 200
assert_equal 'admin', json['data']['attributes']['username']
assert response.headers['X-Auth-Token'].blank?
end

test 'GET show with access_code returns empty user object' do
code = AccessCode.create!(expires_at: 1.month.from_now).code
get :show,
Expand All @@ -41,6 +60,18 @@ class LoginControllerTest < ActionController::TestCase
assert_equal 'speedee', json['data']['attributes']['username']
assert_match /\A#{users(:speedee).id}\$[A-Za-z0-9]{24}\z/,
json['data']['attributes']['api_token']
assert response.headers['X-Auth-Token'].blank?
end

test 'POST login with REMOTE_USER returns admin user object and JWT' do
request.env['REMOTE_USER'] = +'admin'
post :create,
params: { username: 'admin', password: 'foo' }
assert_response 200
assert_equal 'admin', json['data']['attributes']['username']
assert_match /\A#{users(:admin).id}\$[A-Za-z0-9]{24}\z/,
json['data']['attributes']['api_token']
assert response.headers['X-Auth-Token'].present?
end

test 'POST login without REMOTE_USER returns error' do
Expand All @@ -51,9 +82,8 @@ class LoginControllerTest < ActionController::TestCase
end

test 'POST login with api_token responds unauthorized' do
login
post :create,
params: { username: 'speedee', password: 'foo' }
params: { api_token: users(:speedee).api_token }
assert_response 401
end

Expand Down

0 comments on commit 5884ac4

Please sign in to comment.