diff --git a/lib/googleauth/iam.rb b/lib/googleauth/iam.rb new file mode 100644 index 0000000..3632744 --- /dev/null +++ b/lib/googleauth/iam.rb @@ -0,0 +1,75 @@ +# Copyright 2015, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +require 'googleauth/signet' +require 'googleauth/credentials_loader' +require 'multi_json' + +module Google + # Module Auth provides classes that provide Google-specific authorization + # used to access Google APIs. + module Auth + # Authenticates requests using IAM credentials. + class IAMCredentials + SELECTOR_KEY = 'x-goog-iam-authority-selector' + TOKEN_KEY = 'x-goog-iam-authorization-token' + + # Initializes an IAMCredentials. + # + # @param selector the IAM selector. + # @param token the IAM token. + def initialize(selector, token) + fail TypeError unless selector.is_a? String + fail TypeError unless token.is_a? String + @selector = selector + @token = token + end + + # Adds the credential fields to the hash. + def apply!(a_hash) + a_hash[SELECTOR_KEY] = @selector + a_hash[TOKEN_KEY] = @token + a_hash + end + + # Returns a clone of a_hash updated with the authoriation header + def apply(a_hash) + a_copy = a_hash.clone + apply!(a_copy) + a_copy + end + + # Returns a reference to the #apply method, suitable for passing as + # a closure + def updater_proc + lambda(&method(:apply)) + end + end + end +end diff --git a/spec/googleauth/iam_spec.rb b/spec/googleauth/iam_spec.rb new file mode 100644 index 0000000..f7b2b3e --- /dev/null +++ b/spec/googleauth/iam_spec.rb @@ -0,0 +1,80 @@ +# Copyright 2015, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +spec_dir = File.expand_path(File.join(File.dirname(__FILE__))) +$LOAD_PATH.unshift(spec_dir) +$LOAD_PATH.uniq! + +require 'googleauth/iam' + +describe Google::Auth::IAMCredentials do + IAMCredentials = Google::Auth::IAMCredentials + let(:test_selector) { 'the-test-selector' } + let(:test_token) { 'the-test-token' } + let(:test_creds) { IAMCredentials.new(test_selector, test_token) } + + describe '#apply!' do + it 'should update the target hash with the iam values' do + md = { foo: 'bar' } + test_creds.apply!(md) + expect(md[IAMCredentials::SELECTOR_KEY]).to eq test_selector + expect(md[IAMCredentials::TOKEN_KEY]).to eq test_token + expect(md[:foo]).to eq 'bar' + end + end + + describe 'updater_proc' do + it 'should provide a proc that updates a hash with the iam values' do + md = { foo: 'bar' } + the_proc = test_creds.updater_proc + got = the_proc.call(md) + expect(got[IAMCredentials::SELECTOR_KEY]).to eq test_selector + expect(got[IAMCredentials::TOKEN_KEY]).to eq test_token + expect(got[:foo]).to eq 'bar' + end + end + + describe '#apply' do + it 'should not update the original hash with the iam values' do + md = { foo: 'bar' } + test_creds.apply(md) + expect(md[IAMCredentials::SELECTOR_KEY]).to be_nil + expect(md[IAMCredentials::TOKEN_KEY]).to be_nil + expect(md[:foo]).to eq 'bar' + end + + it 'should return a with the iam values' do + md = { foo: 'bar' } + got = test_creds.apply(md) + expect(got[IAMCredentials::SELECTOR_KEY]).to eq test_selector + expect(got[IAMCredentials::TOKEN_KEY]).to eq test_token + expect(got[:foo]).to eq 'bar' + end + end +end