-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implementation of HMAC authorizer (#20)
* Implementation of HMAC authorizer * Add AWSv4 signature authorizer * Bugfixes; auth_handler error processing * Improve error handling * Small fixes
- Loading branch information
Showing
13 changed files
with
318 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
ARG VARIANT="3.0" | ||
FROM mcr.microsoft.com/vscode/devcontainers/ruby:0-${VARIANT} | ||
|
||
ARG DIRENV_VERSION=2.32.1 | ||
|
||
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ | ||
&& apt-get -y install --no-install-recommends jq vim direnv yamllint python3-pip python3-setuptools git less python3-dev | ||
|
||
COPY requirements.txt /tmp/ | ||
RUN pip3 install --requirement /tmp/requirements.txt | ||
|
||
RUN curl --location-trusted https://github.com/direnv/direnv/releases/download/v${DIRENV_VERSION}/direnv.linux-amd64 --output /usr/local/bin/direnv --silent \ | ||
&& chmod +x /usr/local/bin/direnv | ||
|
||
RUN echo -e "setlocal noautoindent\nsetlocal nocindent\nsetlocal nosmartindent\nsetlocal indentexpr=\"\n" > /home/${USER}/.vimrc \ | ||
&& echo 'alias awsume="source awsume"' >> /home/${USER}/.bashrc \ | ||
&& echo 'eval "$(direnv hook bash)"' >> /home/${USER}/.bashrc \ | ||
&& mkdir /home/${USER}/.aws |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
{ | ||
"name": "Ruby", | ||
"build": { | ||
"dockerfile": "Dockerfile", | ||
"args": { | ||
"VARIANT": "3", | ||
"INSTALL_NODE": "false" | ||
} | ||
}, | ||
"mounts": [ | ||
"source=${localEnv:HOME}/.aws,target=/home/vscode/.aws,readonly,type=bind", | ||
"source=${localEnv:HOME}/.ssh,target=/home/vscode/.ssh,readonly,type=bind", | ||
"target=/home/vscode/.aws/cli/cache,type=tmpfs,tmpfs-mode=1777" | ||
], | ||
"extensions": [ | ||
"editorconfig.editorconfig", | ||
"rebornix.ruby", | ||
"redhat.vscode-yaml", | ||
"VisualStudioExptTeam.vscodeintellicode", | ||
"wingrunr21.vscode-ruby" | ||
], | ||
"remoteUser": "vscode", | ||
"remoteEnv": { | ||
"PATH": "/home/vscode/bin:/home/vscode/.local/bin:${containerEnv:PATH}", | ||
|
||
"AWS_ACCESS_KEY_ID": "${localEnv:AWS_ACCESS_KEY_ID}", | ||
"AWS_SECRET_ACCESS_KEY": "${localEnv:AWS_SECRET_ACCESS_KEY}", | ||
"AWS_REGION": "${localEnv:AWS_REGION}", | ||
"AWS_SESSION_TOKEN": "${localEnv:AWS_SESSION_TOKEN}" | ||
}, | ||
"postAttachCommand": "bundle config set --local with 'development' && awsume-configure && direnv allow ${containerWorkspaceFolder} || true" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
awscli | ||
awsume |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,18 @@ | ||
libdir = File.dirname(__FILE__) | ||
$LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir) | ||
|
||
require "train-rest/errors" | ||
require "train-rest/version" | ||
|
||
require "train-rest/transport" | ||
require "train-rest/connection" | ||
|
||
require "train-rest/auth_handler" | ||
require "train-rest/auth_handler/awsv4" | ||
require "train-rest/auth_handler/anonymous" | ||
require "train-rest/auth_handler/authtype-apikey" | ||
require "train-rest/auth_handler/header" | ||
require "train-rest/auth_handler/basic" | ||
require "train-rest/auth_handler/bearer" | ||
require "train-rest/auth_handler/header" | ||
require "train-rest/auth_handler/hmac-signature" | ||
require "train-rest/auth_handler/redfish" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
require 'aws-sigv4' | ||
require 'json' | ||
|
||
require_relative "../auth_handler" | ||
|
||
module TrainPlugins | ||
module Rest | ||
class AWSV4 < AuthHandler | ||
VALID_CREDENTIALS = %w[ | ||
access_keys | ||
].freeze | ||
|
||
SIGNED_HEADERS = %w[ | ||
content-type host x-amz-date x-amz-target | ||
].freeze | ||
|
||
def check_options | ||
options[:credentials] ||= "access_keys" | ||
|
||
unless VALID_CREDENTIALS.include? credentials | ||
raise ArgumentError.new("Invalid type of credentials: #{credentials}") | ||
end | ||
|
||
if access_keys? | ||
raise ArgumentError.new('Missing `access_key` credential') unless access_key | ||
raise ArgumentError.new('Missing `secret_access_key` credential') unless secret_access_key | ||
end | ||
end | ||
|
||
def signature_based? | ||
true | ||
end | ||
|
||
def process(payload: "", headers: {}, url: "", method: nil) | ||
headers.merge! ({ | ||
'Accept-Encoding' => 'identity', | ||
'User-Agent' => "train-rest/#{TrainPlugins::Rest::VERSION}", | ||
'Content-Type' => 'application/x-amz-json-1.0' | ||
}) | ||
|
||
signed_headers = headers.select do |name, _value| | ||
SIGNED_HEADERS.include? name.downcase | ||
end | ||
|
||
@url = url | ||
|
||
signature = signer(url).sign_request( | ||
http_method: method.to_s.upcase, | ||
url: url, | ||
headers: signed_headers, | ||
body: payload.to_json | ||
) | ||
|
||
{ | ||
headers: headers.merge(signature.headers) | ||
} | ||
end | ||
|
||
def process_error(error) | ||
raise AuthenticationError.new("Authentication failed: #{error.response.to_s.chop}") if error.response.code == 401 | ||
raise BadRequest.new("Bad request: #{error.response.to_s.chop}") if error.response.code == 400 | ||
|
||
message = JSON.parse(error.response.to_s) | ||
|
||
raise AuthenticationError.new(message["message"] || message["__type"]) | ||
rescue JSON::ParserError => e | ||
raise AuthenticationError.new(error.response.to_s) | ||
end | ||
|
||
def access_key | ||
options[:access_key] || ENV['AWS_ACCESS_KEY_ID'] | ||
end | ||
|
||
def region(url = default_url) | ||
url.delete_prefix('https://').split('.').at(1) | ||
end | ||
|
||
private | ||
|
||
def credentials | ||
options[:credentials] | ||
end | ||
|
||
def default_url | ||
options[:endpoint] | ||
end | ||
|
||
def access_keys? | ||
credentials == 'access_keys' | ||
end | ||
|
||
def secret_access_key | ||
options[:secret_access_key] || ENV['AWS_SECRET_ACCESS_KEY'] | ||
end | ||
|
||
def service(url) | ||
url.delete_prefix('https://').split('.').at(0) | ||
end | ||
|
||
def signer(url) | ||
Aws::Sigv4::Signer.new( | ||
service: service(url), | ||
region: region(url), | ||
|
||
**signer_credentials | ||
) | ||
end | ||
|
||
def signer_credentials | ||
if access_keys? | ||
{ | ||
access_key_id: access_key, | ||
secret_access_key: secret_access_key | ||
} | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
require_relative "../auth_handler" | ||
|
||
module TrainPlugins | ||
module Rest | ||
# Authentication via HMAC Signature. | ||
class HmacSignature < AuthHandler | ||
def check_options | ||
raise ArgumentError.new("Need :hmac_secret for HMAC signatures") unless options[:hmac_secret] | ||
|
||
options[:header] ||= "X-Signature" | ||
options[:digest] ||= "SHA256" | ||
end | ||
|
||
def hmac_secret | ||
options[:hmac_secret] | ||
end | ||
|
||
def digest | ||
options[:digest] | ||
end | ||
|
||
def header | ||
options[:header] | ||
end | ||
|
||
def signature_based? | ||
true | ||
end | ||
|
||
def process(payload: "", headers: {}, url: "", method: nil) | ||
{ | ||
headers: { | ||
header => OpenSSL::HMAC.hexdigest(digest, hmac_secret, payload) | ||
} | ||
} | ||
end | ||
end | ||
end | ||
end |
Oops, something went wrong.