Skip to content
This repository has been archived by the owner on May 10, 2024. It is now read-only.

Commit

Permalink
Further fixed STS assume_role_with_web_identity.
Browse files Browse the repository at this point in the history
  • Loading branch information
toastdriven committed Aug 19, 2013
1 parent ed1f403 commit ca794d5
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 2 deletions.
39 changes: 39 additions & 0 deletions boto/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,45 @@ def add_auth(self, req, **kwargs):
req.headers['Authorization'] = ','.join(l)


class QueryAuthHandler(AuthHandler):
"""
Provides pure query construction (no actual signing).
Mostly useful for STS' ``assume_role_with_web_identity``.
Does **NOT** escape query string values!
"""

capability = ['pure-query']

def _escape_value(self, value):
# Would normally be ``return urllib.quote(value)``.
return value

def _build_query_string(self, params):
keys = params.keys()
keys.sort(cmp=lambda x, y: cmp(x.lower(), y.lower()))
pairs = []
for key in keys:
val = boto.utils.get_utf8_value(params[key])
pairs.append(key + '=' + self._escape_value(val))
return '&'.join(pairs)

def add_auth(self, http_request, **kwargs):
headers = http_request.headers
params = http_request.params
qs = self._build_query_string(
http_request.params
)
boto.log.debug('query_string: %s' % qs)
headers['Content-Type'] = 'application/json; charset=UTF-8'
http_request.body = ''
# if this is a retried request, the qs from the previous try will
# already be there, we need to get rid of that and rebuild it
http_request.path = http_request.path.split('?')[0]
http_request.path = http_request.path + '?' + qs


class QuerySignatureHelper(HmacKeys):
"""
Helper for Query signature based Auth handler.
Expand Down
4 changes: 2 additions & 2 deletions boto/sts/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ def __init__(self, aws_access_key_id=None, aws_secret_access_key=None,

def _required_auth_capability(self):
if self.anon:
return ['sign-v0']
return ['pure-query']
else:
return ['sign-v2']

Expand Down Expand Up @@ -441,7 +441,7 @@ def assume_role_with_web_identity(self, role_arn, role_session_name,
'AssumeRoleWithWebIdentity',
params,
AssumedRole,
verb='POST'
verb='GET'
)

def decode_authorization_message(self, encoded_message):
Expand Down
76 changes: 76 additions & 0 deletions tests/unit/auth/test_query.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# Copyright (c) 2013 Amazon.com, Inc. or its affiliates. All Rights Reserved
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish, dis-
# tribute, sublicense, and/or sell copies of the Software, and to permit
# persons to whom the Software is furnished to do so, subject to the fol-
# lowing conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
#
import copy
from mock import Mock
from tests.unit import unittest

from boto.auth import QueryAuthHandler
from boto.connection import HTTPRequest


class TestQueryAuthHandler(unittest.TestCase):
def setUp(self):
self.provider = Mock()
self.provider.access_key = 'access_key'
self.provider.secret_key = 'secret_key'
self.request = HTTPRequest(
method='GET',
protocol='https',
host='sts.amazonaws.com',
port=443,
path='/',
auth_path=None,
params={
'Action': 'AssumeRoleWithWebIdentity',
'Version': '2011-06-15',
'RoleSessionName': 'web-identity-federation',
'ProviderId': '2012-06-01',
'WebIdentityToken': 'Atza|IQEBLjAsAhRkcxQ',
},
headers={},
body=''
)

def test_escape_value(self):
auth = QueryAuthHandler('sts.amazonaws.com',
Mock(), self.provider)
# This should **NOT** get escaped.
value = auth._escape_value('Atza|IQEBLjAsAhRkcxQ')
self.assertEqual(value, 'Atza|IQEBLjAsAhRkcxQ')

def test_build_query_string(self):
auth = QueryAuthHandler('sts.amazonaws.com',
Mock(), self.provider)
query_string = auth._build_query_string(self.request.params)
self.assertEqual(query_string, 'Action=AssumeRoleWithWebIdentity' + \
'&ProviderId=2012-06-01&RoleSessionName=web-identity-federation' + \
'&Version=2011-06-15&WebIdentityToken=Atza|IQEBLjAsAhRkcxQ')

def test_add_auth(self):
auth = QueryAuthHandler('sts.amazonaws.com',
Mock(), self.provider)
req = copy.copy(self.request)
auth.add_auth(req)
self.assertEqual(req.path,
'/?Action=AssumeRoleWithWebIdentity' + \
'&ProviderId=2012-06-01&RoleSessionName=web-identity-federation' + \
'&Version=2011-06-15&WebIdentityToken=Atza|IQEBLjAsAhRkcxQ')

0 comments on commit ca794d5

Please sign in to comment.