Skip to content

Commit

Permalink
Merge pull request #178 from abellotti/api_onetime_system_token
Browse files Browse the repository at this point in the history
API Enhancement making the system token a one-time token.
  • Loading branch information
gtanzillo authored Nov 6, 2017
2 parents 9a2767c + 5958775 commit e8c018b
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 1 deletion.
13 changes: 12 additions & 1 deletion app/controllers/api/base_controller/authentication.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
module Api
class BaseController
module Authentication
SYSTEM_TOKEN_ALLOWED_TIME_SKEW = 5.minutes

#
# REST APIs Authenticator and Redirector
#
Expand Down Expand Up @@ -78,6 +80,8 @@ def authenticate_with_user_token(auth_token)
end

def authenticate_with_system_token(x_miq_token)
validate_system_token_otp(x_miq_token)

@miq_token_hash = YAML.load(MiqPassword.decrypt(x_miq_token))

validate_system_token_server(@miq_token_hash[:server_guid])
Expand All @@ -102,7 +106,14 @@ def validate_system_token_server(server_guid)

def validate_system_token_timestamp(timestamp)
raise "Missing timestamp" if timestamp.blank?
raise "Invalid timestamp #{timestamp} specified" if 5.minutes.ago.utc > timestamp
raise "Invalid timestamp #{timestamp} specified" if SYSTEM_TOKEN_ALLOWED_TIME_SKEW.ago.utc > timestamp
end

def validate_system_token_otp(x_miq_token)
token_store = TokenStore.acquire("api_system_token_otp", SYSTEM_TOKEN_ALLOWED_TIME_SKEW)
token_used_timestamp = token_store.read(x_miq_token)
raise "System Token was already used at #{token_used_timestamp}" if token_used_timestamp
token_store.write(x_miq_token, Time.now.getlocal)
end
end
end
Expand Down
16 changes: 16 additions & 0 deletions spec/requests/authentication_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,22 @@ def systoken(server_guid, userid, timestamp)
expect(response).to have_http_status(:ok)
expect_result_to_have_keys(ENTRYPOINT_KEYS)
end

it "authentication using a valid token succeeds only once" do
miq_token = systoken(MiqServer.first.guid, @user.userid, Time.now.utc)

get api_entrypoint_url, :headers => {Api::HttpHeaders::MIQ_TOKEN => miq_token}

expect(response).to have_http_status(:ok)
expect_result_to_have_keys(ENTRYPOINT_KEYS)

get api_entrypoint_url, :headers => {Api::HttpHeaders::MIQ_TOKEN => miq_token}

expect(response).to have_http_status(:unauthorized)
expect(response.parsed_body).to include(
"error" => a_hash_including("kind" => "unauthorized", "message" => AUTHENTICATION_ERROR)
)
end
end

context "Role Based Authorization" do
Expand Down

0 comments on commit e8c018b

Please sign in to comment.