)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"710bb77fcd7bef946f6212ac03e3e444bd3fc426","unresolved":false,"context_lines":[{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Auth plugin authenticating against remote Shibboleth based Identity Providers."},{"line_number":10,"context_line":"Upon successful authentication the plugin retrieves and stores unscoped token."},{"line_number":11,"context_line":"Plugin object should be later used for scopng the token."},{"line_number":12,"context_line":"Currently only Basic Http Auth Method is supported as"},{"line_number":13,"context_line":"an IdP authn method."},{"line_number":14,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":24,"id":"1ae5cdf2_8061bd13","line":11,"updated":"2014-06-16 16:01:19.000000000","message":"scoping","commit_id":"41b5ac952004cac182ae365ea7023450225ad154"},{"author":{"_account_id":8978,"name":"Marek Denis","email":"marek.denis+openstack@gmail.com","username":"marek-denis"},"change_message_id":"42ddb26836ac30a34c819d94ab3e151a46a9676e","unresolved":false,"context_lines":[{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Auth plugin authenticating against remote Shibboleth based Identity Providers."},{"line_number":10,"context_line":"Upon successful authentication the plugin retrieves and stores unscoped token."},{"line_number":11,"context_line":"Plugin object should be later used for scopng the token."},{"line_number":12,"context_line":"Currently only Basic Http Auth Method is supported as"},{"line_number":13,"context_line":"an IdP authn method."},{"line_number":14,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":24,"id":"1ae5cdf2_392e3f8d","line":11,"in_reply_to":"1ae5cdf2_8061bd13","updated":"2014-06-17 10:08:47.000000000","message":"Done","commit_id":"41b5ac952004cac182ae365ea7023450225ad154"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"710bb77fcd7bef946f6212ac03e3e444bd3fc426","unresolved":false,"context_lines":[{"line_number":9,"context_line":"Auth plugin authenticating against remote Shibboleth based Identity Providers."},{"line_number":10,"context_line":"Upon successful authentication the plugin retrieves and stores unscoped token."},{"line_number":11,"context_line":"Plugin object should be later used for scopng the token."},{"line_number":12,"context_line":"Currently only Basic Http Auth Method is supported as"},{"line_number":13,"context_line":"an IdP authn method."},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"Change-Id: Ieea40505a406bedf7219fa6f9e6cf29a45ad6e88"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":24,"id":"1ae5cdf2_c06bc5ef","line":12,"updated":"2014-06-16 16:01:19.000000000","message":"HTTP","commit_id":"41b5ac952004cac182ae365ea7023450225ad154"},{"author":{"_account_id":8978,"name":"Marek Denis","email":"marek.denis+openstack@gmail.com","username":"marek-denis"},"change_message_id":"42ddb26836ac30a34c819d94ab3e151a46a9676e","unresolved":false,"context_lines":[{"line_number":9,"context_line":"Auth plugin authenticating against remote Shibboleth based Identity Providers."},{"line_number":10,"context_line":"Upon successful authentication the plugin retrieves and stores unscoped token."},{"line_number":11,"context_line":"Plugin object should be later used for scopng the token."},{"line_number":12,"context_line":"Currently only Basic Http Auth Method is supported as"},{"line_number":13,"context_line":"an IdP authn method."},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"Change-Id: Ieea40505a406bedf7219fa6f9e6cf29a45ad6e88"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":24,"id":"1ae5cdf2_594ceb76","line":12,"in_reply_to":"1ae5cdf2_c06bc5ef","updated":"2014-06-17 10:08:47.000000000","message":"Done","commit_id":"41b5ac952004cac182ae365ea7023450225ad154"}],"keystoneclient/auth/identity/contrib/federation/saml2.py":[{"author":{"_account_id":2218,"name":"Adam Young","email":"adam@younglogic.com","username":"ayoung"},"change_message_id":"f7881186756843ccf7f52a357ea202e119a8bfd8","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# Copyright 2014 CERN"},{"line_number":2,"context_line":"# Licensed under the Apache License, Version 2.0 (the \"License\"); you may"},{"line_number":3,"context_line":"# not use this file except in compliance with the License. You may obtain"},{"line_number":4,"context_line":"# a copy of the License at"}],"source_content_type":"text/x-python","patch_set":1,"id":"9ad9bd40_039d4e59","line":1,"updated":"2014-05-05 17:36:06.000000000","message":"I think we are dropping these.","commit_id":"971cf1fbbab67e370f4ce38c51e4040b8ef22616"},{"author":{"_account_id":2218,"name":"Adam Young","email":"adam@younglogic.com","username":"ayoung"},"change_message_id":"f7881186756843ccf7f52a357ea202e119a8bfd8","unresolved":false,"context_lines":[{"line_number":27,"context_line":"                          \u0027password\u0027]"},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"    def __init__(self, **kwargs):"},{"line_number":30,"context_line":"        \"\"\"Construct a HttpBasic ECP SAML2 authentication method."},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"        :param string identity_provider: Name of the identity_provider the"},{"line_number":33,"context_line":"                                         client authenticates against."}],"source_content_type":"text/x-python","patch_set":1,"id":"9ad9bd40_0302ae6e","line":30,"updated":"2014-05-05 17:36:06.000000000","message":"Could Kerberos or X509 Client auth be used in conjunction with this?  Instead of Basic Auth?  I realize that The Kerberos requests library is not yet available.","commit_id":"971cf1fbbab67e370f4ce38c51e4040b8ef22616"},{"author":{"_account_id":8978,"name":"Marek Denis","email":"marek.denis+openstack@gmail.com","username":"marek-denis"},"change_message_id":"75c28644936c0d68304cd3a96be77fc2f1da279c","unresolved":false,"context_lines":[{"line_number":27,"context_line":"                          \u0027password\u0027]"},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"    def __init__(self, **kwargs):"},{"line_number":30,"context_line":"        \"\"\"Construct a HttpBasic ECP SAML2 authentication method."},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"        :param string identity_provider: Name of the identity_provider the"},{"line_number":33,"context_line":"                                         client authenticates against."}],"source_content_type":"text/x-python","patch_set":1,"id":"9ad9bd40_ee24ca61","line":30,"in_reply_to":"9ad9bd40_0302ae6e","updated":"2014-05-05 21:11:16.000000000","message":"Yes, ECP is rather a transport layer (SOAP over HTTP), and doesn\u0027t enforce any authentication mechanism. However, the Http BasicAuth is probably the most common as it corresponds webform authentication. I have in mind some more fancy mechanisms that would load plugins for identity provider authentication - basic auth, kerberos, X509 etc.","commit_id":"971cf1fbbab67e370f4ce38c51e4040b8ef22616"},{"author":{"_account_id":2218,"name":"Adam Young","email":"adam@younglogic.com","username":"ayoung"},"change_message_id":"f7881186756843ccf7f52a357ea202e119a8bfd8","unresolved":false,"context_lines":[{"line_number":38,"context_line":"        \"\"\""},{"line_number":39,"context_line":"        super(Saml2Method, self).__init__(**kwargs)"},{"line_number":40,"context_line":""},{"line_number":41,"context_line":"    #NOTE(marek-denis): Maybe we should even raise some exception here."},{"line_number":42,"context_line":"    def get_auth_data(self, session, auth, headers, **kwargs):"},{"line_number":43,"context_line":"        \"\"\"Return empty authentication section of an SAML2 auth plugin"},{"line_number":44,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"9ad9bd40_c3e446e3","line":41,"updated":"2014-05-05 17:36:06.000000000","message":"Drop the note, as you do raise an exception.","commit_id":"971cf1fbbab67e370f4ce38c51e4040b8ef22616"},{"author":{"_account_id":2218,"name":"Adam Young","email":"adam@younglogic.com","username":"ayoung"},"change_message_id":"f7881186756843ccf7f52a357ea202e119a8bfd8","unresolved":false,"context_lines":[{"line_number":58,"context_line":""},{"line_number":59,"context_line":"    TEXT_HTML_CONTENT_TYPE \u003d {"},{"line_number":60,"context_line":"    \u0027Content-type\u0027: \u0027text/html\u0027"},{"line_number":61,"context_line":"    }"},{"line_number":62,"context_line":"    "},{"line_number":63,"context_line":"    ECP_SP_REQ_HEADERS \u003d {"},{"line_number":64,"context_line":"        \u0027Accept\u0027: \u0027text/html; application/vnd.paos+xml\u0027,"}],"source_content_type":"text/x-python","patch_set":1,"id":"9ad9bd40_43c91658","line":61,"updated":"2014-05-05 17:36:06.000000000","message":"Whitespace","commit_id":"971cf1fbbab67e370f4ce38c51e4040b8ef22616"},{"author":{"_account_id":2218,"name":"Adam Young","email":"adam@younglogic.com","username":"ayoung"},"change_message_id":"f7881186756843ccf7f52a357ea202e119a8bfd8","unresolved":false,"context_lines":[{"line_number":60,"context_line":"    \u0027Content-type\u0027: \u0027text/html\u0027"},{"line_number":61,"context_line":"    }"},{"line_number":62,"context_line":"    "},{"line_number":63,"context_line":"    ECP_SP_REQ_HEADERS \u003d {"},{"line_number":64,"context_line":"        \u0027Accept\u0027: \u0027text/html; application/vnd.paos+xml\u0027,"},{"line_number":65,"context_line":"        \u0027PAOS\u0027: (\u0027ver\u003d\"urn:liberty:paos:2003-08\";\"urn:oasis:names:tc:\u0027"},{"line_number":66,"context_line":"                 \u0027SAML:2.0:profiles:SSO:ecp\"\u0027)"}],"source_content_type":"text/x-python","patch_set":1,"id":"9ad9bd40_63ab7a75","line":63,"updated":"2014-05-05 17:36:06.000000000","message":"ECP?  Spell it out in a comment, and provide a link to the appropriate spec or RFC.","commit_id":"971cf1fbbab67e370f4ce38c51e4040b8ef22616"},{"author":{"_account_id":2218,"name":"Adam Young","email":"adam@younglogic.com","username":"ayoung"},"change_message_id":"f7881186756843ccf7f52a357ea202e119a8bfd8","unresolved":false,"context_lines":[{"line_number":91,"context_line":"        super(Saml2, self).__init__(auth_url\u003dauth_url,"},{"line_number":92,"context_line":"                                    auth_methods\u003dauth_methods, **kwargs)"},{"line_number":93,"context_line":""},{"line_number":94,"context_line":"    def _sp_request(self):"},{"line_number":95,"context_line":"        \"\"\"Initial HTTP GET request to the SAML2 protected endpoint."},{"line_number":96,"context_line":""},{"line_number":97,"context_line":"        It\u0027s crucial to include HTTP requests indicating that the client is "}],"source_content_type":"text/x-python","patch_set":1,"id":"9ad9bd40_23a5f2a1","line":94,"updated":"2014-05-05 17:36:06.000000000","message":"sp?  Serviceprovider?  At least provide a comment explaining what it means.","commit_id":"971cf1fbbab67e370f4ce38c51e4040b8ef22616"},{"author":{"_account_id":7186,"name":"Matthieu Huin","email":"mhuin@redhat.com","username":"mhu"},"change_message_id":"395a14cd4349566647ebef8040f6d6e79eb156f7","unresolved":false,"context_lines":[{"line_number":97,"context_line":"            raise IndexError(\"Only single element list can be flatten\")"},{"line_number":98,"context_line":"        return _list[0]"},{"line_number":99,"context_line":""},{"line_number":100,"context_line":"    def _prepare_idp_saml2_request(self):"},{"line_number":101,"context_line":"        header \u003d saml2_authn_request[self.SAML2_HEADER_INDEX]"},{"line_number":102,"context_line":"        saml2_authn_request.remove(header)"},{"line_number":103,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"9ad9bd40_145006d3","line":100,"updated":"2014-05-06 15:59:50.000000000","message":"missing argument according to #158 and it should return something ?","commit_id":"b8cd0a55601633c32151b1f80681cfccda95212b"},{"author":{"_account_id":7186,"name":"Matthieu Huin","email":"mhuin@redhat.com","username":"mhu"},"change_message_id":"395a14cd4349566647ebef8040f6d6e79eb156f7","unresolved":false,"context_lines":[{"line_number":191,"context_line":"            headers\u003dself.ECP_SP_SAML2_REQUEST_HEADERS,"},{"line_number":192,"context_line":"            data\u003dservice_provider_saml2_assertion, authenticated\u003dFalse)"},{"line_number":193,"context_line":""},{"line_number":194,"context_line":"        self.authnenticated_response \u003d response"},{"line_number":195,"context_line":""},{"line_number":196,"context_line":"    @property"},{"line_number":197,"context_line":"    def token_url(self):"}],"source_content_type":"text/x-python","patch_set":2,"id":"9ad9bd40_54d7ee4a","line":194,"updated":"2014-05-06 15:59:50.000000000","message":"typo: authenticated","commit_id":"b8cd0a55601633c32151b1f80681cfccda95212b"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"8af25f1bf8514964c32cc0d42045dae35663ee41","unresolved":false,"context_lines":[{"line_number":279,"context_line":"        # shibboleth-authenticated"},{"line_number":280,"context_line":""},{"line_number":281,"context_line":"        try:"},{"line_number":282,"context_line":"            self.saml2_authn_request \u003d etree.XML(sp_response.text)"},{"line_number":283,"context_line":"        except AttributeError:"},{"line_number":284,"context_line":"            msg \u003d (\"SAML2: Bad Service Provider \""},{"line_number":285,"context_line":"                   \"response, reason: %s\" % response.reason)"}],"source_content_type":"text/x-python","patch_set":14,"id":"1ae5cdf2_a0582f57","line":282,"updated":"2014-06-10 16:15:52.000000000","message":"You probably don\u0027t want to use the text property here. In Python 3 this is a string instead of bytes. Instead use \u0027content\u0027.","commit_id":"e60954df06fcbd176733f1ed9fb2886ac92f9370"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"8af25f1bf8514964c32cc0d42045dae35663ee41","unresolved":false,"context_lines":[{"line_number":312,"context_line":"            requests_auth\u003d(self.username, self.password), verify\u003dFalse)"},{"line_number":313,"context_line":""},{"line_number":314,"context_line":"        try:"},{"line_number":315,"context_line":"            self.saml2_idp_authn_response \u003d etree.XML(str(idp_response.text))"},{"line_number":316,"context_line":"        except AttributeError:"},{"line_number":317,"context_line":"            msg \u003d (\"SAML2: Bad Identity Provider \""},{"line_number":318,"context_line":"                   \"response, reason: %s\" % response.reason)"}],"source_content_type":"text/x-python","patch_set":14,"id":"1ae5cdf2_40168b56","line":315,"updated":"2014-06-10 16:15:52.000000000","message":"Same as above","commit_id":"e60954df06fcbd176733f1ed9fb2886ac92f9370"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"6b68bacb00777e4dc092efde51c266f63b13a623","unresolved":false,"context_lines":[{"line_number":27,"context_line":"    def get_auth_data(self, session, auth, headers, **kwargs):"},{"line_number":28,"context_line":"        \"\"\"Build and return request body for token scoping step.\"\"\""},{"line_number":29,"context_line":"        if not hasattr(auth, \u0027authenticated_response\u0027):"},{"line_number":30,"context_line":"            raise AttributeError(\"Missing authenticated_response, \""},{"line_number":31,"context_line":"                                 \"get unscoped token first.\")"},{"line_number":32,"context_line":"        try:"},{"line_number":33,"context_line":"            saml2 \u003d {\u0027id\u0027: auth.authenticated_response.headers["}],"source_content_type":"text/x-python","patch_set":15,"id":"1ae5cdf2_39a37650","line":30,"updated":"2014-06-10 17:15:19.000000000","message":"I\u0027m curious about this. It seems like you may want to use a Keystone client specific exception.","commit_id":"3572f8ce2176daf88633a574adf18a25a169d643"},{"author":{"_account_id":8978,"name":"Marek Denis","email":"marek.denis+openstack@gmail.com","username":"marek-denis"},"change_message_id":"2e99cf0df47ac77a73cd1aa41371f4f8829f6e48","unresolved":false,"context_lines":[{"line_number":27,"context_line":"    def get_auth_data(self, session, auth, headers, **kwargs):"},{"line_number":28,"context_line":"        \"\"\"Build and return request body for token scoping step.\"\"\""},{"line_number":29,"context_line":"        if not hasattr(auth, \u0027authenticated_response\u0027):"},{"line_number":30,"context_line":"            raise AttributeError(\"Missing authenticated_response, \""},{"line_number":31,"context_line":"                                 \"get unscoped token first.\")"},{"line_number":32,"context_line":"        try:"},{"line_number":33,"context_line":"            saml2 \u003d {\u0027id\u0027: auth.authenticated_response.headers["}],"source_content_type":"text/x-python","patch_set":15,"id":"1ae5cdf2_65b0f18b","line":30,"in_reply_to":"1ae5cdf2_39a37650","updated":"2014-06-10 20:27:45.000000000","message":"changed to exceptions.Unauthorized, however not 100% sure this is a good exception to be used. InvalidResponse?","commit_id":"3572f8ce2176daf88633a574adf18a25a169d643"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"6b68bacb00777e4dc092efde51c266f63b13a623","unresolved":false,"context_lines":[{"line_number":32,"context_line":"        try:"},{"line_number":33,"context_line":"            saml2 \u003d {\u0027id\u0027: auth.authenticated_response.headers["},{"line_number":34,"context_line":"                \u0027X-Subject-Token\u0027]}"},{"line_number":35,"context_line":"        except (KeyError, ValueError):"},{"line_number":36,"context_line":"            raise exceptions.InvalidResponse("},{"line_number":37,"context_line":"                response\u003dauth.authenticated_response)"},{"line_number":38,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":15,"id":"1ae5cdf2_f9158e9b","line":35,"updated":"2014-06-10 17:15:19.000000000","message":"What could cause a ValueError here? Can you add a test to show?\n\nWhat about a KeyError? I assume it\u0027s because the header may not be available, but there is no test to show that.\n\nI removed the except and all of the tests still passed.","commit_id":"3572f8ce2176daf88633a574adf18a25a169d643"},{"author":{"_account_id":8978,"name":"Marek Denis","email":"marek.denis+openstack@gmail.com","username":"marek-denis"},"change_message_id":"2e99cf0df47ac77a73cd1aa41371f4f8829f6e48","unresolved":false,"context_lines":[{"line_number":32,"context_line":"        try:"},{"line_number":33,"context_line":"            saml2 \u003d {\u0027id\u0027: auth.authenticated_response.headers["},{"line_number":34,"context_line":"                \u0027X-Subject-Token\u0027]}"},{"line_number":35,"context_line":"        except (KeyError, ValueError):"},{"line_number":36,"context_line":"            raise exceptions.InvalidResponse("},{"line_number":37,"context_line":"                response\u003dauth.authenticated_response)"},{"line_number":38,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":15,"id":"1ae5cdf2_0a99fa1e","line":35,"in_reply_to":"1ae5cdf2_f9158e9b","updated":"2014-06-10 20:27:45.000000000","message":"yes, KeyError is protection from not having X-Subject-Token in the headers.\nValueError...hm, I think I\u0027s my copy/paste effect :( \n\ni will remove ValueError and add a test for KeyError catching.","commit_id":"3572f8ce2176daf88633a574adf18a25a169d643"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"6b68bacb00777e4dc092efde51c266f63b13a623","unresolved":false,"context_lines":[{"line_number":39,"context_line":"            return self._method_name, saml2"},{"line_number":40,"context_line":""},{"line_number":41,"context_line":""},{"line_number":42,"context_line":"class Saml2(v3._AuthConstructor):"},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"    _auth_method_class \u003d Saml2Method"},{"line_number":45,"context_line":""}],"source_content_type":"text/x-python","patch_set":15,"id":"1ae5cdf2_b98ea6ce","line":42,"updated":"2014-06-10 17:15:19.000000000","message":"Seems like the class name shouldn\u0027t begin with _ since it\u0027s used outside of it\u0027s module.","commit_id":"3572f8ce2176daf88633a574adf18a25a169d643"},{"author":{"_account_id":8978,"name":"Marek Denis","email":"marek.denis+openstack@gmail.com","username":"marek-denis"},"change_message_id":"2e99cf0df47ac77a73cd1aa41371f4f8829f6e48","unresolved":false,"context_lines":[{"line_number":39,"context_line":"            return self._method_name, saml2"},{"line_number":40,"context_line":""},{"line_number":41,"context_line":""},{"line_number":42,"context_line":"class Saml2(v3._AuthConstructor):"},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"    _auth_method_class \u003d Saml2Method"},{"line_number":45,"context_line":""}],"source_content_type":"text/x-python","patch_set":15,"id":"1ae5cdf2_2aa07642","line":42,"in_reply_to":"1ae5cdf2_b98ea6ce","updated":"2014-06-10 20:27:45.000000000","message":"what can I say...I only work here :-)","commit_id":"3572f8ce2176daf88633a574adf18a25a169d643"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"6b68bacb00777e4dc092efde51c266f63b13a623","unresolved":false,"context_lines":[{"line_number":85,"context_line":""},{"line_number":86,"context_line":"    def __init__(self, auth_url, identity_provider,"},{"line_number":87,"context_line":"                 identity_provider_url, project_id\u003dNone, domain_id\u003dNone,"},{"line_number":88,"context_line":"                 **kwargs):"},{"line_number":89,"context_line":"        \"\"\"Implement authentication plugin for SAML2 protocol."},{"line_number":90,"context_line":""},{"line_number":91,"context_line":"        ECP stands for ``Enhanced Client or Proxy`` and is a SAML2 extension"}],"source_content_type":"text/x-python","patch_set":15,"id":"1ae5cdf2_f934aefc","line":88,"updated":"2014-06-10 17:15:19.000000000","message":"Is there any reason that username and password are treated like first-class parameters here and documented in the docstring?","commit_id":"3572f8ce2176daf88633a574adf18a25a169d643"},{"author":{"_account_id":8978,"name":"Marek Denis","email":"marek.denis+openstack@gmail.com","username":"marek-denis"},"change_message_id":"2e99cf0df47ac77a73cd1aa41371f4f8829f6e48","unresolved":false,"context_lines":[{"line_number":85,"context_line":""},{"line_number":86,"context_line":"    def __init__(self, auth_url, identity_provider,"},{"line_number":87,"context_line":"                 identity_provider_url, project_id\u003dNone, domain_id\u003dNone,"},{"line_number":88,"context_line":"                 **kwargs):"},{"line_number":89,"context_line":"        \"\"\"Implement authentication plugin for SAML2 protocol."},{"line_number":90,"context_line":""},{"line_number":91,"context_line":"        ECP stands for ``Enhanced Client or Proxy`` and is a SAML2 extension"}],"source_content_type":"text/x-python","patch_set":15,"id":"1ae5cdf2_c56705b6","line":88,"in_reply_to":"1ae5cdf2_f934aefc","updated":"2014-06-10 20:27:45.000000000","message":"well, this is a PoC with BasicAuth method hardcoded in the plugin. In a future, this plugin should actually accept IdP-authn plugins - objects responsible for authentication against the IdP. I feel we should do this that way, as it\u0027s not specified in the SAML2 specs how user should authenticate against IdP. The most popular way is via HttpBasicAuth, but I think not the only one. I think I will try to build that on top of https://review.openstack.org/#/c/79542/ .","commit_id":"3572f8ce2176daf88633a574adf18a25a169d643"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"6b68bacb00777e4dc092efde51c266f63b13a623","unresolved":false,"context_lines":[{"line_number":88,"context_line":"                 **kwargs):"},{"line_number":89,"context_line":"        \"\"\"Implement authentication plugin for SAML2 protocol."},{"line_number":90,"context_line":""},{"line_number":91,"context_line":"        ECP stands for ``Enhanced Client or Proxy`` and is a SAML2 extension"},{"line_number":92,"context_line":"        for federated authentication where a transportation layer consists of"},{"line_number":93,"context_line":"        HTTP protocol and XML SOAP messages."},{"line_number":94,"context_line":""}],"source_content_type":"text/x-python","patch_set":15,"id":"1ae5cdf2_545ba92d","line":91,"updated":"2014-06-10 17:15:19.000000000","message":"Much of this seems like it would be a better fit for the class docstring.","commit_id":"3572f8ce2176daf88633a574adf18a25a169d643"},{"author":{"_account_id":8978,"name":"Marek Denis","email":"marek.denis+openstack@gmail.com","username":"marek-denis"},"change_message_id":"2e99cf0df47ac77a73cd1aa41371f4f8829f6e48","unresolved":false,"context_lines":[{"line_number":88,"context_line":"                 **kwargs):"},{"line_number":89,"context_line":"        \"\"\"Implement authentication plugin for SAML2 protocol."},{"line_number":90,"context_line":""},{"line_number":91,"context_line":"        ECP stands for ``Enhanced Client or Proxy`` and is a SAML2 extension"},{"line_number":92,"context_line":"        for federated authentication where a transportation layer consists of"},{"line_number":93,"context_line":"        HTTP protocol and XML SOAP messages."},{"line_number":94,"context_line":""}],"source_content_type":"text/x-python","patch_set":15,"id":"1ae5cdf2_6a899ec9","line":91,"in_reply_to":"1ae5cdf2_545ba92d","updated":"2014-06-10 20:27:45.000000000","message":"moved there!","commit_id":"3572f8ce2176daf88633a574adf18a25a169d643"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"6b68bacb00777e4dc092efde51c266f63b13a623","unresolved":false,"context_lines":[{"line_number":498,"context_line":"          /v3/src/markdown/identity-api-v3-os-federation-ext.md#request-a-"},{"line_number":499,"context_line":"          scoped-os-federation-token-post-authtokens\u003e`_"},{"line_number":500,"context_line":""},{"line_number":501,"context_line":"        In case project_id or domain_id are not set explicitely, this plugin"},{"line_number":502,"context_line":"        will list all accessible projects and domains and raise an exception"},{"line_number":503,"context_line":"        exceptions.CannotScope with json dictionary with accessible projects"},{"line_number":504,"context_line":"        and domains returned from the server. User should repeat authentication"}],"source_content_type":"text/x-python","patch_set":15,"id":"1ae5cdf2_74c42592","line":501,"range":{"start_line":501,"start_character":52,"end_line":501,"end_character":63},"updated":"2014-06-10 17:15:19.000000000","message":"explicitly?","commit_id":"3572f8ce2176daf88633a574adf18a25a169d643"},{"author":{"_account_id":8978,"name":"Marek Denis","email":"marek.denis+openstack@gmail.com","username":"marek-denis"},"change_message_id":"2e99cf0df47ac77a73cd1aa41371f4f8829f6e48","unresolved":false,"context_lines":[{"line_number":498,"context_line":"          /v3/src/markdown/identity-api-v3-os-federation-ext.md#request-a-"},{"line_number":499,"context_line":"          scoped-os-federation-token-post-authtokens\u003e`_"},{"line_number":500,"context_line":""},{"line_number":501,"context_line":"        In case project_id or domain_id are not set explicitely, this plugin"},{"line_number":502,"context_line":"        will list all accessible projects and domains and raise an exception"},{"line_number":503,"context_line":"        exceptions.CannotScope with json dictionary with accessible projects"},{"line_number":504,"context_line":"        and domains returned from the server. User should repeat authentication"}],"source_content_type":"text/x-python","patch_set":15,"id":"1ae5cdf2_49022f3f","line":501,"in_reply_to":"1ae5cdf2_74c42592","updated":"2014-06-10 20:27:45.000000000","message":"Done","commit_id":"3572f8ce2176daf88633a574adf18a25a169d643"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"6b68bacb00777e4dc092efde51c266f63b13a623","unresolved":false,"context_lines":[{"line_number":504,"context_line":"        and domains returned from the server. User should repeat authentication"},{"line_number":505,"context_line":"        process with setting project_id or domain_id."},{"line_number":506,"context_line":""},{"line_number":507,"context_line":"        :param session : a session object to send out HTTP requests."},{"line_number":508,"context_line":"        :type session: keystoneclient.session.Session"},{"line_number":509,"context_line":""},{"line_number":510,"context_line":"        :return access.AccessInfoV3: an object with scoped token_id and scoped"}],"source_content_type":"text/x-python","patch_set":15,"id":"1ae5cdf2_744b452b","line":507,"updated":"2014-06-10 17:15:19.000000000","message":"Space after session","commit_id":"3572f8ce2176daf88633a574adf18a25a169d643"},{"author":{"_account_id":8978,"name":"Marek Denis","email":"marek.denis+openstack@gmail.com","username":"marek-denis"},"change_message_id":"2e99cf0df47ac77a73cd1aa41371f4f8829f6e48","unresolved":false,"context_lines":[{"line_number":504,"context_line":"        and domains returned from the server. User should repeat authentication"},{"line_number":505,"context_line":"        process with setting project_id or domain_id."},{"line_number":506,"context_line":""},{"line_number":507,"context_line":"        :param session : a session object to send out HTTP requests."},{"line_number":508,"context_line":"        :type session: keystoneclient.session.Session"},{"line_number":509,"context_line":""},{"line_number":510,"context_line":"        :return access.AccessInfoV3: an object with scoped token_id and scoped"}],"source_content_type":"text/x-python","patch_set":15,"id":"1ae5cdf2_69fd2b3b","line":507,"in_reply_to":"1ae5cdf2_744b452b","updated":"2014-06-10 20:27:45.000000000","message":"Done","commit_id":"3572f8ce2176daf88633a574adf18a25a169d643"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"6b68bacb00777e4dc092efde51c266f63b13a623","unresolved":false,"context_lines":[{"line_number":512,"context_line":""},{"line_number":513,"context_line":"        \"\"\""},{"line_number":514,"context_line":"        self._get_unscoped_token(session, **kwargs)"},{"line_number":515,"context_line":"        if not any(bool(x) for x in [self.project_id, self.domain_id]):"},{"line_number":516,"context_line":"            projects \u003d self._list_projects(session)"},{"line_number":517,"context_line":"            domains \u003d self._list_domains(session)"},{"line_number":518,"context_line":"            raise exceptions.CannotScope(projects\u003dprojects, domains\u003ddomains)"}],"source_content_type":"text/x-python","patch_set":15,"id":"1ae5cdf2_94d8d180","line":515,"updated":"2014-06-10 17:15:19.000000000","message":"Is this just saying \u0027if not (self.project_id or self.domain_id)\u0027?","commit_id":"3572f8ce2176daf88633a574adf18a25a169d643"},{"author":{"_account_id":8978,"name":"Marek Denis","email":"marek.denis+openstack@gmail.com","username":"marek-denis"},"change_message_id":"2e99cf0df47ac77a73cd1aa41371f4f8829f6e48","unresolved":false,"context_lines":[{"line_number":512,"context_line":""},{"line_number":513,"context_line":"        \"\"\""},{"line_number":514,"context_line":"        self._get_unscoped_token(session, **kwargs)"},{"line_number":515,"context_line":"        if not any(bool(x) for x in [self.project_id, self.domain_id]):"},{"line_number":516,"context_line":"            projects \u003d self._list_projects(session)"},{"line_number":517,"context_line":"            domains \u003d self._list_domains(session)"},{"line_number":518,"context_line":"            raise exceptions.CannotScope(projects\u003dprojects, domains\u003ddomains)"}],"source_content_type":"text/x-python","patch_set":15,"id":"1ae5cdf2_89fc3740","line":515,"in_reply_to":"1ae5cdf2_94d8d180","updated":"2014-06-10 20:27:45.000000000","message":"yes.","commit_id":"3572f8ce2176daf88633a574adf18a25a169d643"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"3fd8eb43d5584c3d388da1c707098a080eb81717","unresolved":false,"context_lines":[{"line_number":126,"context_line":"        if response.status_code !\u003d self.HTTP_MOVED_TEMPORARILY:"},{"line_number":127,"context_line":"            return response"},{"line_number":128,"context_line":""},{"line_number":129,"context_line":"        location \u003d response.headers[\u0027location\u0027]"},{"line_number":130,"context_line":"        return session.request(location, method, **kwargs)"},{"line_number":131,"context_line":""},{"line_number":132,"context_line":"    def flatten_list(self, _list):"}],"source_content_type":"text/x-python","patch_set":16,"id":"1ae5cdf2_3577edd5","line":129,"updated":"2014-06-10 23:19:00.000000000","message":"The thing we work around in requests is it changing a POST to a GET on 302. We prevent that in session and make sure that it keeps the same method.\n\nAs you aren\u0027t changing the method I can\u0027t see that this does anything.","commit_id":"a6c9df537002e5f5bff1d22b6ec03ec83f14befe"},{"author":{"_account_id":8978,"name":"Marek Denis","email":"marek.denis+openstack@gmail.com","username":"marek-denis"},"change_message_id":"35fce037d3d78faaad70b5f5ddc7125eb7dba292","unresolved":false,"context_lines":[{"line_number":126,"context_line":"        if response.status_code !\u003d self.HTTP_MOVED_TEMPORARILY:"},{"line_number":127,"context_line":"            return response"},{"line_number":128,"context_line":""},{"line_number":129,"context_line":"        location \u003d response.headers[\u0027location\u0027]"},{"line_number":130,"context_line":"        return session.request(location, method, **kwargs)"},{"line_number":131,"context_line":""},{"line_number":132,"context_line":"    def flatten_list(self, _list):"}],"source_content_type":"text/x-python","patch_set":16,"id":"1ae5cdf2_05447619","line":129,"in_reply_to":"1ae5cdf2_3577edd5","updated":"2014-06-11 08:21:36.000000000","message":"but here I don\u0027t send again the request\u0027s body, see how I call this method in line 366. This is how it shibboleth is implemented and I cannot do anything about it: \n- After I authenticate against IdP I am getting SAML assertion. I must pass this assertion to a shibboleth endpoint something like keystone.com/Shibboleth.sso/SOAP/ECP . This assertion is accepted, parsed, parameters are now available in the environemnt, the session is created (cookie stores in a session object) and shibboleth returns HTTP 302 with \u0027location\u0027 variable set to protected resource (v3/OS-FEDERATION/identit_providers/{idp}/protocols/{protocol}/auth). This means, that when I enter this protected resource I will get access to something available there - Keystone! If I now send my SAML2 assertion again (as an effect of redirection), this body will get to the Keystone. And Keystone will not understand what\u0027s that, returning HTTP 400, claiming this is a bad request.","commit_id":"a6c9df537002e5f5bff1d22b6ec03ec83f14befe"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"3fd8eb43d5584c3d388da1c707098a080eb81717","unresolved":false,"context_lines":[{"line_number":159,"context_line":"        if sp_response_consumer_url !\u003d idp_sp_response_consumer_url:"},{"line_number":160,"context_line":"            # send fault message to the SP, discard the response"},{"line_number":161,"context_line":"            session.post(sp_response_consumer_url, data\u003dself.SOAP_FAULT,"},{"line_number":162,"context_line":"                         headers\u003dself.ECP_SP_SAML2_REQUEST_HEADERS)"},{"line_number":163,"context_line":""},{"line_number":164,"context_line":"            # prepare error message and raise an exception."},{"line_number":165,"context_line":"            msg \u003d (\"Consumer URLs from Service Provider %(service_provider)s \""}],"source_content_type":"text/x-python","patch_set":16,"id":"1ae5cdf2_b54a1d81","line":162,"updated":"2014-06-10 23:19:00.000000000","message":"authenticated\u003dFalse or you could end up in a loop","commit_id":"a6c9df537002e5f5bff1d22b6ec03ec83f14befe"},{"author":{"_account_id":8978,"name":"Marek Denis","email":"marek.denis+openstack@gmail.com","username":"marek-denis"},"change_message_id":"35fce037d3d78faaad70b5f5ddc7125eb7dba292","unresolved":false,"context_lines":[{"line_number":159,"context_line":"        if sp_response_consumer_url !\u003d idp_sp_response_consumer_url:"},{"line_number":160,"context_line":"            # send fault message to the SP, discard the response"},{"line_number":161,"context_line":"            session.post(sp_response_consumer_url, data\u003dself.SOAP_FAULT,"},{"line_number":162,"context_line":"                         headers\u003dself.ECP_SP_SAML2_REQUEST_HEADERS)"},{"line_number":163,"context_line":""},{"line_number":164,"context_line":"            # prepare error message and raise an exception."},{"line_number":165,"context_line":"            msg \u003d (\"Consumer URLs from Service Provider %(service_provider)s \""}],"source_content_type":"text/x-python","patch_set":16,"id":"1ae5cdf2_059c765c","line":162,"in_reply_to":"1ae5cdf2_b54a1d81","updated":"2014-06-11 08:21:36.000000000","message":"Done","commit_id":"a6c9df537002e5f5bff1d22b6ec03ec83f14befe"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"3fd8eb43d5584c3d388da1c707098a080eb81717","unresolved":false,"context_lines":[{"line_number":253,"context_line":""},{"line_number":254,"context_line":"        return access.AccessInfoV3("},{"line_number":255,"context_line":"            scoped_token_id,"},{"line_number":256,"context_line":"            **scoped_token)"},{"line_number":257,"context_line":""},{"line_number":258,"context_line":"    def _send_service_provider_request(self, session):"},{"line_number":259,"context_line":"        \"\"\"Initial HTTP GET request to the SAML2 protected endpoint."}],"source_content_type":"text/x-python","patch_set":16,"id":"1ae5cdf2_882fc887","line":256,"updated":"2014-06-10 23:19:00.000000000","message":"instead of c\u0026p this why not just define a new v3.Auth subclass?","commit_id":"a6c9df537002e5f5bff1d22b6ec03ec83f14befe"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"3fd8eb43d5584c3d388da1c707098a080eb81717","unresolved":false,"context_lines":[{"line_number":275,"context_line":"        \"\"\""},{"line_number":276,"context_line":"        sp_response \u003d session.get(self.saml2_token_url,"},{"line_number":277,"context_line":"                                  headers\u003dself.ECP_SP_EMPTY_REQUEST_HEADERS,"},{"line_number":278,"context_line":"                                  verify\u003dFalse)"},{"line_number":279,"context_line":"        # NOTE(marek-denis):"},{"line_number":280,"context_line":"        # we might somehow need to care if the session is"},{"line_number":281,"context_line":"        # shibboleth-authenticated"}],"source_content_type":"text/x-python","patch_set":16,"id":"1ae5cdf2_483ce0bf","line":278,"updated":"2014-06-10 23:19:00.000000000","message":"authenticated\u003dFalse","commit_id":"a6c9df537002e5f5bff1d22b6ec03ec83f14befe"},{"author":{"_account_id":8978,"name":"Marek Denis","email":"marek.denis+openstack@gmail.com","username":"marek-denis"},"change_message_id":"35fce037d3d78faaad70b5f5ddc7125eb7dba292","unresolved":false,"context_lines":[{"line_number":275,"context_line":"        \"\"\""},{"line_number":276,"context_line":"        sp_response \u003d session.get(self.saml2_token_url,"},{"line_number":277,"context_line":"                                  headers\u003dself.ECP_SP_EMPTY_REQUEST_HEADERS,"},{"line_number":278,"context_line":"                                  verify\u003dFalse)"},{"line_number":279,"context_line":"        # NOTE(marek-denis):"},{"line_number":280,"context_line":"        # we might somehow need to care if the session is"},{"line_number":281,"context_line":"        # shibboleth-authenticated"}],"source_content_type":"text/x-python","patch_set":16,"id":"1ae5cdf2_a5b742d7","line":278,"in_reply_to":"1ae5cdf2_483ce0bf","updated":"2014-06-11 08:21:36.000000000","message":"Done","commit_id":"a6c9df537002e5f5bff1d22b6ec03ec83f14befe"}],"keystoneclient/contrib/auth/v3/saml2.py":[{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"710bb77fcd7bef946f6212ac03e3e444bd3fc426","unresolved":false,"context_lines":[{"line_number":103,"context_line":"        super(Saml2UnscopedToken, self).__init__(auth_url\u003dauth_url, **kwargs)"},{"line_number":104,"context_line":"        self.identity_provider \u003d identity_provider"},{"line_number":105,"context_line":"        self.identity_provider_url \u003d identity_provider_url"},{"line_number":106,"context_line":"        self.username \u003d kwargs.get(\u0027username\u0027)"},{"line_number":107,"context_line":"        self.password \u003d kwargs.get(\u0027password\u0027)"},{"line_number":108,"context_line":"        self.token_json \u003d None"},{"line_number":109,"context_line":"        self.token \u003d None"}],"source_content_type":"text/x-python","patch_set":24,"id":"1ae5cdf2_9f5d9718","line":106,"updated":"2014-06-16 16:01:19.000000000","message":"I would make these kwargs if they are optional, but looking at the rest of the code leads me to believe that they are actually required. If they are not required there should be a test showing the expected behavior when they are not provided.","commit_id":"41b5ac952004cac182ae365ea7023450225ad154"},{"author":{"_account_id":8978,"name":"Marek Denis","email":"marek.denis+openstack@gmail.com","username":"marek-denis"},"change_message_id":"42ddb26836ac30a34c819d94ab3e151a46a9676e","unresolved":false,"context_lines":[{"line_number":103,"context_line":"        super(Saml2UnscopedToken, self).__init__(auth_url\u003dauth_url, **kwargs)"},{"line_number":104,"context_line":"        self.identity_provider \u003d identity_provider"},{"line_number":105,"context_line":"        self.identity_provider_url \u003d identity_provider_url"},{"line_number":106,"context_line":"        self.username \u003d kwargs.get(\u0027username\u0027)"},{"line_number":107,"context_line":"        self.password \u003d kwargs.get(\u0027password\u0027)"},{"line_number":108,"context_line":"        self.token_json \u003d None"},{"line_number":109,"context_line":"        self.token \u003d None"}],"source_content_type":"text/x-python","patch_set":24,"id":"1ae5cdf2_16c31239","line":106,"in_reply_to":"1ae5cdf2_9f5d9718","updated":"2014-06-17 10:08:47.000000000","message":"OK, I made them appear in the function signature. There is also a new test, however I am not really sure it\u0027s necessary as it raises TypeError due to bad number of arguments passed to the function.","commit_id":"41b5ac952004cac182ae365ea7023450225ad154"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"710bb77fcd7bef946f6212ac03e3e444bd3fc426","unresolved":false,"context_lines":[{"line_number":304,"context_line":""},{"line_number":305,"context_line":"        return url"},{"line_number":306,"context_line":""},{"line_number":307,"context_line":"    def clean(self):"},{"line_number":308,"context_line":"        \"\"\"Explicitely delete attributes used during multi-step authn.\"\"\""},{"line_number":309,"context_line":"        attrs \u003d [\u0027saml2_authn_request\u0027, \u0027relay_state\u0027,"},{"line_number":310,"context_line":"                 \u0027service_provider_consumer_url\u0027, \u0027saml2_idp_authn_response\u0027]"}],"source_content_type":"text/x-python","patch_set":24,"id":"1ae5cdf2_e28b641c","line":307,"updated":"2014-06-16 16:01:19.000000000","message":"This class is strange because I can\u0027t tell the lifecycle by looking at it. Do instances get reused? Is that why things are not declared in the __init__ and are cleared up here?","commit_id":"41b5ac952004cac182ae365ea7023450225ad154"},{"author":{"_account_id":8978,"name":"Marek Denis","email":"marek.denis+openstack@gmail.com","username":"marek-denis"},"change_message_id":"42ddb26836ac30a34c819d94ab3e151a46a9676e","unresolved":false,"context_lines":[{"line_number":304,"context_line":""},{"line_number":305,"context_line":"        return url"},{"line_number":306,"context_line":""},{"line_number":307,"context_line":"    def clean(self):"},{"line_number":308,"context_line":"        \"\"\"Explicitely delete attributes used during multi-step authn.\"\"\""},{"line_number":309,"context_line":"        attrs \u003d [\u0027saml2_authn_request\u0027, \u0027relay_state\u0027,"},{"line_number":310,"context_line":"                 \u0027service_provider_consumer_url\u0027, \u0027saml2_idp_authn_response\u0027]"}],"source_content_type":"text/x-python","patch_set":24,"id":"1ae5cdf2_f6c78663","line":307,"in_reply_to":"1ae5cdf2_e28b641c","updated":"2014-06-17 10:08:47.000000000","message":"No, i don\u0027t think they should be reused. Maybe the best idea is to delete this method and let GC to take care of proper deleting the properties.\n\nActually the only think we might want to reuse to optimize the workflow is the cookies stored in the Session object. But it\u0027s not cleaned :-)","commit_id":"41b5ac952004cac182ae365ea7023450225ad154"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"deb1d4e30313deccaefda159c7b5f621406bd21a","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":29,"id":"dab895d6_4d8d3931","updated":"2014-06-29 07:38:01.000000000","message":"I thought this would be in\n\nkeystoneclient.v3.contrib.federation.auth\n\nwas there a suggestion by someone else to move it here?","commit_id":"24ce620789f878fa78ce34869ab96700c6eb7347"},{"author":{"_account_id":8978,"name":"Marek Denis","email":"marek.denis+openstack@gmail.com","username":"marek-denis"},"change_message_id":"d447283b413e5e8715ef1d6162d08a8135497c7f","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":29,"id":"dab895d6_21064021","in_reply_to":"dab895d6_4d8d3931","updated":"2014-06-30 10:27:05.000000000","message":"Jamie Lennox, see his comment on Patch 16.\n\n\"can we move this to keystoneclient/contrib/auth/v3?\"","commit_id":"24ce620789f878fa78ce34869ab96700c6eb7347"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"deb1d4e30313deccaefda159c7b5f621406bd21a","unresolved":false,"context_lines":[{"line_number":109,"context_line":"    \u003c/S:Envelope\u003e"},{"line_number":110,"context_line":"    \"\"\""},{"line_number":111,"context_line":""},{"line_number":112,"context_line":"    def __init__(self, auth_url,"},{"line_number":113,"context_line":"                 idp_auth_plugin,"},{"line_number":114,"context_line":"                 identity_provider,"},{"line_number":115,"context_line":"                 identity_provider_url,"}],"source_content_type":"text/x-python","patch_set":29,"id":"dab895d6_4d09b994","line":112,"updated":"2014-06-29 07:38:01.000000000","message":"do we really need the auth_url for this step?","commit_id":"24ce620789f878fa78ce34869ab96700c6eb7347"},{"author":{"_account_id":8978,"name":"Marek Denis","email":"marek.denis+openstack@gmail.com","username":"marek-denis"},"change_message_id":"d447283b413e5e8715ef1d6162d08a8135497c7f","unresolved":false,"context_lines":[{"line_number":109,"context_line":"    \u003c/S:Envelope\u003e"},{"line_number":110,"context_line":"    \"\"\""},{"line_number":111,"context_line":""},{"line_number":112,"context_line":"    def __init__(self, auth_url,"},{"line_number":113,"context_line":"                 idp_auth_plugin,"},{"line_number":114,"context_line":"                 identity_provider,"},{"line_number":115,"context_line":"                 identity_provider_url,"}],"source_content_type":"text/x-python","patch_set":29,"id":"dab895d6_41f9744c","line":112,"in_reply_to":"dab895d6_4d09b994","updated":"2014-06-30 10:27:05.000000000","message":"I would say yes. auth_url is usually keystone url (at least its prefix), and here we access Keystone serving in a SP role.\nIt\u0027s used e.g. in get_saml2_token() method below and normally it\u0027s used in https://github.com/openstack/python-keystoneclient/blob/master/keystoneclient/auth/identity/v3.py#L62","commit_id":"24ce620789f878fa78ce34869ab96700c6eb7347"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"deb1d4e30313deccaefda159c7b5f621406bd21a","unresolved":false,"context_lines":[{"line_number":123,"context_line":"                                  obtain unscoped OpenStack token."},{"line_number":124,"context_line":"        :type identity_provider: string"},{"line_number":125,"context_line":"        :param idp_auth_plugin: Object authenticating against the IdP."},{"line_number":126,"context_line":"        :type idp_auth_plugin: Class inheriting from ``saml2.IdPAuth``"},{"line_number":127,"context_line":""},{"line_number":128,"context_line":"        :param identity_provider_url: An Identity Provider URL, where the SAML2"},{"line_number":129,"context_line":"                                      authn request will be sent."}],"source_content_type":"text/x-python","patch_set":29,"id":"dab895d6_6d0cbd95","line":126,"updated":"2014-06-29 07:38:01.000000000","message":"nit: i\u0027d move these up a few lines as they are the second argument, but 3rd on this list","commit_id":"24ce620789f878fa78ce34869ab96700c6eb7347"},{"author":{"_account_id":8978,"name":"Marek Denis","email":"marek.denis+openstack@gmail.com","username":"marek-denis"},"change_message_id":"d447283b413e5e8715ef1d6162d08a8135497c7f","unresolved":false,"context_lines":[{"line_number":123,"context_line":"                                  obtain unscoped OpenStack token."},{"line_number":124,"context_line":"        :type identity_provider: string"},{"line_number":125,"context_line":"        :param idp_auth_plugin: Object authenticating against the IdP."},{"line_number":126,"context_line":"        :type idp_auth_plugin: Class inheriting from ``saml2.IdPAuth``"},{"line_number":127,"context_line":""},{"line_number":128,"context_line":"        :param identity_provider_url: An Identity Provider URL, where the SAML2"},{"line_number":129,"context_line":"                                      authn request will be sent."}],"source_content_type":"text/x-python","patch_set":29,"id":"dab895d6_c1ed848d","line":126,"in_reply_to":"dab895d6_6d0cbd95","updated":"2014-06-30 10:27:05.000000000","message":"Done","commit_id":"24ce620789f878fa78ce34869ab96700c6eb7347"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"dd5183446638a5a87572489ed244773a4322f874","unresolved":false,"context_lines":[{"line_number":136,"context_line":"        if response.status_code !\u003d self.HTTP_MOVED_TEMPORARILY:"},{"line_number":137,"context_line":"            return response"},{"line_number":138,"context_line":""},{"line_number":139,"context_line":"        location \u003d response.headers[\u0027location\u0027]"},{"line_number":140,"context_line":"        return session.request(location, method, **kwargs)"},{"line_number":141,"context_line":""},{"line_number":142,"context_line":"    def flatten_list(self, _list):"}],"source_content_type":"text/x-python","patch_set":35,"id":"baada198_9d553520","line":139,"updated":"2014-07-11 15:43:15.000000000","message":"This doesn\u0027t appear to be called. Is it actually needed?","commit_id":"1863490e544d24155e8e8ae9d5590296ca70b111"},{"author":{"_account_id":8978,"name":"Marek Denis","email":"marek.denis+openstack@gmail.com","username":"marek-denis"},"change_message_id":"e1ce57721afa837d3230b27be60e8fb85c5a1319","unresolved":false,"context_lines":[{"line_number":136,"context_line":"        if response.status_code !\u003d self.HTTP_MOVED_TEMPORARILY:"},{"line_number":137,"context_line":"            return response"},{"line_number":138,"context_line":""},{"line_number":139,"context_line":"        location \u003d response.headers[\u0027location\u0027]"},{"line_number":140,"context_line":"        return session.request(location, method, **kwargs)"},{"line_number":141,"context_line":""},{"line_number":142,"context_line":"    def flatten_list(self, _list):"}],"source_content_type":"text/x-python","patch_set":35,"id":"baada198_35a35501","line":139,"in_reply_to":"baada198_9d553520","updated":"2014-07-11 19:16:32.000000000","message":"yes it is. Also test for that was added.","commit_id":"1863490e544d24155e8e8ae9d5590296ca70b111"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"dd5183446638a5a87572489ed244773a4322f874","unresolved":false,"context_lines":[{"line_number":140,"context_line":"        return session.request(location, method, **kwargs)"},{"line_number":141,"context_line":""},{"line_number":142,"context_line":"    def flatten_list(self, _list):"},{"line_number":143,"context_line":"        if len(_list) !\u003d 1:"},{"line_number":144,"context_line":"            raise IndexError(\"Only single element list can be flatten\")"},{"line_number":145,"context_line":"        return _list[0]"},{"line_number":146,"context_line":""}],"source_content_type":"text/x-python","patch_set":35,"id":"baada198_80e5cc0a","line":143,"updated":"2014-07-11 15:43:15.000000000","message":"Nothing seems to pass in anything other than a list of a single item. Is there a known case where we may get something else?","commit_id":"1863490e544d24155e8e8ae9d5590296ca70b111"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"dd5183446638a5a87572489ed244773a4322f874","unresolved":false,"context_lines":[{"line_number":214,"context_line":"        try:"},{"line_number":215,"context_line":"            self.saml2_authn_request \u003d etree.XML(sp_response.content)"},{"line_number":216,"context_line":"        except AttributeError:"},{"line_number":217,"context_line":"            msg \u003d (\"SAML2: Bad Service Provider \""},{"line_number":218,"context_line":"                   \"response, reason: %s\" % response.reason)"},{"line_number":219,"context_line":"            raise exceptions.AuthorizationFailure(msg)"},{"line_number":220,"context_line":"        except etree.XMLSyntaxError as e:"}],"source_content_type":"text/x-python","patch_set":35,"id":"baada198_0306261d","line":217,"updated":"2014-07-11 15:43:15.000000000","message":"What will raise the attribute error here? The test don\u0027t invoke this benavior.","commit_id":"1863490e544d24155e8e8ae9d5590296ca70b111"},{"author":{"_account_id":8978,"name":"Marek Denis","email":"marek.denis+openstack@gmail.com","username":"marek-denis"},"change_message_id":"e1ce57721afa837d3230b27be60e8fb85c5a1319","unresolved":false,"context_lines":[{"line_number":214,"context_line":"        try:"},{"line_number":215,"context_line":"            self.saml2_authn_request \u003d etree.XML(sp_response.content)"},{"line_number":216,"context_line":"        except AttributeError:"},{"line_number":217,"context_line":"            msg \u003d (\"SAML2: Bad Service Provider \""},{"line_number":218,"context_line":"                   \"response, reason: %s\" % response.reason)"},{"line_number":219,"context_line":"            raise exceptions.AuthorizationFailure(msg)"},{"line_number":220,"context_line":"        except etree.XMLSyntaxError as e:"}],"source_content_type":"text/x-python","patch_set":35,"id":"baada198_d5b3f94a","line":217,"in_reply_to":"baada198_0306261d","updated":"2014-07-11 19:16:32.000000000","message":"removed that exception handler","commit_id":"1863490e544d24155e8e8ae9d5590296ca70b111"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"dd5183446638a5a87572489ed244773a4322f874","unresolved":false,"context_lines":[{"line_number":248,"context_line":"        try:"},{"line_number":249,"context_line":"            self.saml2_idp_authn_response \u003d etree.XML(idp_response.content)"},{"line_number":250,"context_line":"        except AttributeError:"},{"line_number":251,"context_line":"            msg \u003d (\"SAML2: Bad Identity Provider \""},{"line_number":252,"context_line":"                   \"response, reason: %s\" % response.reason)"},{"line_number":253,"context_line":"            raise exceptions.AuthorizationFailure(msg)"},{"line_number":254,"context_line":"        except etree.XMLSyntaxError as e:"}],"source_content_type":"text/x-python","patch_set":35,"id":"baada198_800a2c24","line":251,"updated":"2014-07-11 15:43:15.000000000","message":"What will raise the attribute error here? The test don\u0027t invoke this benavior.","commit_id":"1863490e544d24155e8e8ae9d5590296ca70b111"},{"author":{"_account_id":8978,"name":"Marek Denis","email":"marek.denis+openstack@gmail.com","username":"marek-denis"},"change_message_id":"e1ce57721afa837d3230b27be60e8fb85c5a1319","unresolved":false,"context_lines":[{"line_number":248,"context_line":"        try:"},{"line_number":249,"context_line":"            self.saml2_idp_authn_response \u003d etree.XML(idp_response.content)"},{"line_number":250,"context_line":"        except AttributeError:"},{"line_number":251,"context_line":"            msg \u003d (\"SAML2: Bad Identity Provider \""},{"line_number":252,"context_line":"                   \"response, reason: %s\" % response.reason)"},{"line_number":253,"context_line":"            raise exceptions.AuthorizationFailure(msg)"},{"line_number":254,"context_line":"        except etree.XMLSyntaxError as e:"}],"source_content_type":"text/x-python","patch_set":35,"id":"baada198_f5839d53","line":251,"in_reply_to":"baada198_800a2c24","updated":"2014-07-11 19:16:32.000000000","message":"removed that exception handler","commit_id":"1863490e544d24155e8e8ae9d5590296ca70b111"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"dd5183446638a5a87572489ed244773a4322f874","unresolved":false,"context_lines":[{"line_number":392,"context_line":"        \"\"\""},{"line_number":393,"context_line":"        saml_authenticated \u003d self._send_service_provider_request(session)"},{"line_number":394,"context_line":"        if not saml_authenticated:"},{"line_number":395,"context_line":"            self._send_idp_saml2_authn_request(session)"},{"line_number":396,"context_line":"            self._send_service_provider_saml2_authn_response(session)"},{"line_number":397,"context_line":"        self._extract_token_from_response()"},{"line_number":398,"context_line":""}],"source_content_type":"text/x-python","patch_set":35,"id":"baada198_209de00a","line":395,"updated":"2014-07-11 15:43:15.000000000","message":"The tests exercise _send_service_provider_request to check for the case that returns False, but that doesn\u0027t happen in the case where this method is called.","commit_id":"1863490e544d24155e8e8ae9d5590296ca70b111"},{"author":{"_account_id":8978,"name":"Marek Denis","email":"marek.denis+openstack@gmail.com","username":"marek-denis"},"change_message_id":"e1ce57721afa837d3230b27be60e8fb85c5a1319","unresolved":false,"context_lines":[{"line_number":392,"context_line":"        \"\"\""},{"line_number":393,"context_line":"        saml_authenticated \u003d self._send_service_provider_request(session)"},{"line_number":394,"context_line":"        if not saml_authenticated:"},{"line_number":395,"context_line":"            self._send_idp_saml2_authn_request(session)"},{"line_number":396,"context_line":"            self._send_service_provider_saml2_authn_response(session)"},{"line_number":397,"context_line":"        self._extract_token_from_response()"},{"line_number":398,"context_line":""}],"source_content_type":"text/x-python","patch_set":35,"id":"baada198_23aeca81","line":395,"in_reply_to":"baada198_209de00a","updated":"2014-07-11 19:16:32.000000000","message":"correct. Probably the proper way to inclue the test is expose all \u0027remote\u0027 endpoints (SP, IdP) and try complex authN","commit_id":"1863490e544d24155e8e8ae9d5590296ca70b111"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"dd5183446638a5a87572489ed244773a4322f874","unresolved":false,"context_lines":[{"line_number":396,"context_line":"            self._send_service_provider_saml2_authn_response(session)"},{"line_number":397,"context_line":"        self._extract_token_from_response()"},{"line_number":398,"context_line":""},{"line_number":399,"context_line":"    def get_auth_ref(self, session, **kwargs):"},{"line_number":400,"context_line":"        \"\"\"Authenticate via SAML2 protocol and retrieve unscoped token."},{"line_number":401,"context_line":""},{"line_number":402,"context_line":"        This is a multi-step process where a client does federated authn"}],"source_content_type":"text/x-python","patch_set":35,"id":"baada198_c0c26452","line":399,"updated":"2014-07-11 15:43:15.000000000","message":"This doesn\u0027t get called during the test run, is it actually used? If so, in what case?","commit_id":"1863490e544d24155e8e8ae9d5590296ca70b111"},{"author":{"_account_id":8978,"name":"Marek Denis","email":"marek.denis+openstack@gmail.com","username":"marek-denis"},"change_message_id":"e1ce57721afa837d3230b27be60e8fb85c5a1319","unresolved":false,"context_lines":[{"line_number":396,"context_line":"            self._send_service_provider_saml2_authn_response(session)"},{"line_number":397,"context_line":"        self._extract_token_from_response()"},{"line_number":398,"context_line":""},{"line_number":399,"context_line":"    def get_auth_ref(self, session, **kwargs):"},{"line_number":400,"context_line":"        \"\"\"Authenticate via SAML2 protocol and retrieve unscoped token."},{"line_number":401,"context_line":""},{"line_number":402,"context_line":"        This is a multi-step process where a client does federated authn"}],"source_content_type":"text/x-python","patch_set":35,"id":"baada198_439c9e5d","line":399,"in_reply_to":"baada198_c0c26452","updated":"2014-07-11 19:16:32.000000000","message":"it\u0027s the standard method called to get a token. We need it, since the authN workflow here is not very standard (multiple calls instead of one POST request to /auth/tokens)","commit_id":"1863490e544d24155e8e8ae9d5590296ca70b111"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"90d371c8ac677a9528f9ec6ec7e7cd67e7bd8b2f","unresolved":false,"context_lines":[{"line_number":15,"context_line":"from keystoneclient import access"},{"line_number":16,"context_line":"from keystoneclient.auth.identity import v3"},{"line_number":17,"context_line":"from keystoneclient import exceptions"},{"line_number":18,"context_line":"from oslo.config import cfg"},{"line_number":19,"context_line":""},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"class Saml2UnscopedTokenAuthMethod(v3.AuthMethod):"}],"source_content_type":"text/x-python","patch_set":39,"id":"baada198_b59cc56b","line":18,"updated":"2014-07-11 19:25:03.000000000","message":"This should be up in the thirdparty lib section.","commit_id":"bfcc5e5d91779e29050336fe1d6152dda0d7d778"},{"author":{"_account_id":8978,"name":"Marek Denis","email":"marek.denis+openstack@gmail.com","username":"marek-denis"},"change_message_id":"e0d2304453e3ec858f0281db3719374378acee8d","unresolved":false,"context_lines":[{"line_number":15,"context_line":"from keystoneclient import access"},{"line_number":16,"context_line":"from keystoneclient.auth.identity import v3"},{"line_number":17,"context_line":"from keystoneclient import exceptions"},{"line_number":18,"context_line":"from oslo.config import cfg"},{"line_number":19,"context_line":""},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"class Saml2UnscopedTokenAuthMethod(v3.AuthMethod):"}],"source_content_type":"text/x-python","patch_set":39,"id":"baada198_b54be5af","line":18,"in_reply_to":"baada198_b59cc56b","updated":"2014-07-11 20:25:51.000000000","message":"Done","commit_id":"bfcc5e5d91779e29050336fe1d6152dda0d7d778"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"90d371c8ac677a9528f9ec6ec7e7cd67e7bd8b2f","unresolved":false,"context_lines":[{"line_number":29,"context_line":"class Saml2UnscopedToken(v3.AuthConstructor):"},{"line_number":30,"context_line":"    \"\"\"Implement authentication plugin for SAML2 protocol."},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"        ECP stands for ``Enhanced Client or Proxy`` and is a SAML2 extension"},{"line_number":33,"context_line":"        for federated authentication where a transportation layer consists of"},{"line_number":34,"context_line":"        HTTP protocol and XML SOAP messages."},{"line_number":35,"context_line":""}],"source_content_type":"text/x-python","patch_set":39,"id":"baada198_555a892a","line":32,"updated":"2014-07-11 19:25:03.000000000","message":"This line and below should not be indented 8 spaces. It should only be 4.","commit_id":"bfcc5e5d91779e29050336fe1d6152dda0d7d778"},{"author":{"_account_id":8978,"name":"Marek Denis","email":"marek.denis+openstack@gmail.com","username":"marek-denis"},"change_message_id":"e0d2304453e3ec858f0281db3719374378acee8d","unresolved":false,"context_lines":[{"line_number":29,"context_line":"class Saml2UnscopedToken(v3.AuthConstructor):"},{"line_number":30,"context_line":"    \"\"\"Implement authentication plugin for SAML2 protocol."},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"        ECP stands for ``Enhanced Client or Proxy`` and is a SAML2 extension"},{"line_number":33,"context_line":"        for federated authentication where a transportation layer consists of"},{"line_number":34,"context_line":"        HTTP protocol and XML SOAP messages."},{"line_number":35,"context_line":""}],"source_content_type":"text/x-python","patch_set":39,"id":"baada198_cb1a7cc5","line":32,"in_reply_to":"baada198_555a892a","updated":"2014-07-11 20:25:51.000000000","message":"Done","commit_id":"bfcc5e5d91779e29050336fe1d6152dda0d7d778"},{"author":{"_account_id":2218,"name":"Adam Young","email":"adam@younglogic.com","username":"ayoung"},"change_message_id":"8806e4243573d7002d89f63280ad5bd76c0f44cd","unresolved":false,"context_lines":[{"line_number":139,"context_line":"        location \u003d response.headers[\u0027location\u0027]"},{"line_number":140,"context_line":"        return session.request(location, method, **kwargs)"},{"line_number":141,"context_line":""},{"line_number":142,"context_line":"    def flatten_list(self, _list):"},{"line_number":143,"context_line":"        if len(_list) !\u003d 1:"},{"line_number":144,"context_line":"            raise IndexError(\"Only single element list can be flatten\")"},{"line_number":145,"context_line":"        return _list[0]"}],"source_content_type":"text/x-python","patch_set":39,"id":"baada198_0ffc8771","line":142,"updated":"2014-07-11 17:33:56.000000000","message":"_internal:  also \u0027_first\u0027  not \u0027flatten\u0027","commit_id":"bfcc5e5d91779e29050336fe1d6152dda0d7d778"},{"author":{"_account_id":8978,"name":"Marek Denis","email":"marek.denis+openstack@gmail.com","username":"marek-denis"},"change_message_id":"f7edfefe66355dcf00dd683c6459aa07e246adee","unresolved":false,"context_lines":[{"line_number":139,"context_line":"        location \u003d response.headers[\u0027location\u0027]"},{"line_number":140,"context_line":"        return session.request(location, method, **kwargs)"},{"line_number":141,"context_line":""},{"line_number":142,"context_line":"    def flatten_list(self, _list):"},{"line_number":143,"context_line":"        if len(_list) !\u003d 1:"},{"line_number":144,"context_line":"            raise IndexError(\"Only single element list can be flatten\")"},{"line_number":145,"context_line":"        return _list[0]"}],"source_content_type":"text/x-python","patch_set":39,"id":"baada198_d7c22152","line":142,"in_reply_to":"baada198_0ffc8771","updated":"2014-07-11 19:15:00.000000000","message":"Done","commit_id":"bfcc5e5d91779e29050336fe1d6152dda0d7d778"},{"author":{"_account_id":2218,"name":"Adam Young","email":"adam@younglogic.com","username":"ayoung"},"change_message_id":"8806e4243573d7002d89f63280ad5bd76c0f44cd","unresolved":false,"context_lines":[{"line_number":243,"context_line":"            self.identity_provider_url,"},{"line_number":244,"context_line":"            headers\u003d{\u0027Content-type\u0027: \u0027text/html\u0027},"},{"line_number":245,"context_line":"            data\u003detree.tostring(idp_saml2_authn_request),"},{"line_number":246,"context_line":"            requests_auth\u003d(self.username, self.password), verify\u003dFalse)"},{"line_number":247,"context_line":""},{"line_number":248,"context_line":"        try:"},{"line_number":249,"context_line":"            self.saml2_idp_authn_response \u003d etree.XML(idp_response.content)"}],"source_content_type":"text/x-python","patch_set":39,"id":"baada198_efcd9332","line":246,"updated":"2014-07-11 17:33:56.000000000","message":"verify should be a config option, but default to True","commit_id":"bfcc5e5d91779e29050336fe1d6152dda0d7d778"},{"author":{"_account_id":8978,"name":"Marek Denis","email":"marek.denis+openstack@gmail.com","username":"marek-denis"},"change_message_id":"f7edfefe66355dcf00dd683c6459aa07e246adee","unresolved":false,"context_lines":[{"line_number":243,"context_line":"            self.identity_provider_url,"},{"line_number":244,"context_line":"            headers\u003d{\u0027Content-type\u0027: \u0027text/html\u0027},"},{"line_number":245,"context_line":"            data\u003detree.tostring(idp_saml2_authn_request),"},{"line_number":246,"context_line":"            requests_auth\u003d(self.username, self.password), verify\u003dFalse)"},{"line_number":247,"context_line":""},{"line_number":248,"context_line":"        try:"},{"line_number":249,"context_line":"            self.saml2_idp_authn_response \u003d etree.XML(idp_response.content)"}],"source_content_type":"text/x-python","patch_set":39,"id":"baada198_1719f9d6","line":246,"in_reply_to":"baada198_efcd9332","updated":"2014-07-11 19:15:00.000000000","message":"Done","commit_id":"bfcc5e5d91779e29050336fe1d6152dda0d7d778"},{"author":{"_account_id":2218,"name":"Adam Young","email":"adam@younglogic.com","username":"ayoung"},"change_message_id":"8806e4243573d7002d89f63280ad5bd76c0f44cd","unresolved":false,"context_lines":[{"line_number":302,"context_line":""},{"line_number":303,"context_line":"        self.authenticated_response \u003d response"},{"line_number":304,"context_line":""},{"line_number":305,"context_line":"    def _extract_token_from_response(self):"},{"line_number":306,"context_line":"        try:"},{"line_number":307,"context_line":"            self.token_json \u003d self.authenticated_response.json()[\u0027token\u0027]"},{"line_number":308,"context_line":"            self.token \u003d self.authenticated_response.headers["}],"source_content_type":"text/x-python","patch_set":39,"id":"baada198_aff63b5b","line":305,"updated":"2014-07-11 17:33:56.000000000","message":"Do this in common plugin code, not your own version","commit_id":"bfcc5e5d91779e29050336fe1d6152dda0d7d778"},{"author":{"_account_id":8978,"name":"Marek Denis","email":"marek.denis+openstack@gmail.com","username":"marek-denis"},"change_message_id":"f7edfefe66355dcf00dd683c6459aa07e246adee","unresolved":false,"context_lines":[{"line_number":302,"context_line":""},{"line_number":303,"context_line":"        self.authenticated_response \u003d response"},{"line_number":304,"context_line":""},{"line_number":305,"context_line":"    def _extract_token_from_response(self):"},{"line_number":306,"context_line":"        try:"},{"line_number":307,"context_line":"            self.token_json \u003d self.authenticated_response.json()[\u0027token\u0027]"},{"line_number":308,"context_line":"            self.token \u003d self.authenticated_response.headers["}],"source_content_type":"text/x-python","patch_set":39,"id":"baada198_5a12b809","line":305,"in_reply_to":"baada198_aff63b5b","updated":"2014-07-11 19:15:00.000000000","message":"removed,","commit_id":"bfcc5e5d91779e29050336fe1d6152dda0d7d778"},{"author":{"_account_id":2218,"name":"Adam Young","email":"adam@younglogic.com","username":"ayoung"},"change_message_id":"8806e4243573d7002d89f63280ad5bd76c0f44cd","unresolved":false,"context_lines":[{"line_number":394,"context_line":"        if not saml_authenticated:"},{"line_number":395,"context_line":"            self._send_idp_saml2_authn_request(session)"},{"line_number":396,"context_line":"            self._send_service_provider_saml2_authn_response(session)"},{"line_number":397,"context_line":"        self._extract_token_from_response()"},{"line_number":398,"context_line":""},{"line_number":399,"context_line":"    def get_auth_ref(self, session, **kwargs):"},{"line_number":400,"context_line":"        \"\"\"Authenticate via SAML2 protocol and retrieve unscoped token."}],"source_content_type":"text/x-python","patch_set":39,"id":"baada198_cf4b6f85","line":397,"range":{"start_line":397,"start_character":8,"end_line":397,"end_character":42},"updated":"2014-07-11 17:33:56.000000000","message":"remove","commit_id":"bfcc5e5d91779e29050336fe1d6152dda0d7d778"},{"author":{"_account_id":8978,"name":"Marek Denis","email":"marek.denis+openstack@gmail.com","username":"marek-denis"},"change_message_id":"f7edfefe66355dcf00dd683c6459aa07e246adee","unresolved":false,"context_lines":[{"line_number":394,"context_line":"        if not saml_authenticated:"},{"line_number":395,"context_line":"            self._send_idp_saml2_authn_request(session)"},{"line_number":396,"context_line":"            self._send_service_provider_saml2_authn_response(session)"},{"line_number":397,"context_line":"        self._extract_token_from_response()"},{"line_number":398,"context_line":""},{"line_number":399,"context_line":"    def get_auth_ref(self, session, **kwargs):"},{"line_number":400,"context_line":"        \"\"\"Authenticate via SAML2 protocol and retrieve unscoped token."}],"source_content_type":"text/x-python","patch_set":39,"id":"baada198_7afa1cbe","line":397,"in_reply_to":"baada198_cf4b6f85","updated":"2014-07-11 19:15:00.000000000","message":"Done","commit_id":"bfcc5e5d91779e29050336fe1d6152dda0d7d778"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"770abfaee3f24c72182ea395d9205eb215ca92ad","unresolved":false,"context_lines":[{"line_number":242,"context_line":"        # Currently HTTPBasicAuth method is hardcoded into the plugin"},{"line_number":243,"context_line":"        idp_response \u003d session.post("},{"line_number":244,"context_line":"            self.identity_provider_url,"},{"line_number":245,"context_line":"            headers\u003d{\u0027Content-type\u0027: \u0027text/html\u0027},"},{"line_number":246,"context_line":"            data\u003detree.tostring(idp_saml2_authn_request),"},{"line_number":247,"context_line":"            requests_auth\u003d(self.username, self.password))"},{"line_number":248,"context_line":""}],"source_content_type":"text/x-python","patch_set":42,"id":"baada198_f5c16f30","line":245,"updated":"2014-07-15 20:09:06.000000000","message":"so i had to change this to text/xml to get TFIM working.","commit_id":"67fc3636770587d33dca26eacb225fe98b16fe9f"},{"author":{"_account_id":8978,"name":"Marek Denis","email":"marek.denis+openstack@gmail.com","username":"marek-denis"},"change_message_id":"9df143cd56f511568dd36ce4b9da60a1303b3471","unresolved":false,"context_lines":[{"line_number":242,"context_line":"        # Currently HTTPBasicAuth method is hardcoded into the plugin"},{"line_number":243,"context_line":"        idp_response \u003d session.post("},{"line_number":244,"context_line":"            self.identity_provider_url,"},{"line_number":245,"context_line":"            headers\u003d{\u0027Content-type\u0027: \u0027text/html\u0027},"},{"line_number":246,"context_line":"            data\u003detree.tostring(idp_saml2_authn_request),"},{"line_number":247,"context_line":"            requests_auth\u003d(self.username, self.password))"},{"line_number":248,"context_line":""}],"source_content_type":"text/x-python","patch_set":42,"id":"baada198_53b4f3d3","line":245,"in_reply_to":"baada198_f5c16f30","updated":"2014-07-15 21:07:05.000000000","message":"yeah, worked for Shibboleth too, so let\u0027s change to text/xml :-)","commit_id":"67fc3636770587d33dca26eacb225fe98b16fe9f"}],"keystoneclient/exceptions.py":[{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"6b68bacb00777e4dc092efde51c266f63b13a623","unresolved":false,"context_lines":[{"line_number":84,"context_line":""},{"line_number":85,"context_line":"class CannotScope(ClientException):"},{"line_number":86,"context_line":""},{"line_number":87,"context_line":"    def __init__(self, projects, domains):"},{"line_number":88,"context_line":"        self.projects \u003d projects"},{"line_number":89,"context_line":"        self.domains \u003d domains"}],"source_content_type":"text/x-python","patch_set":15,"id":"1ae5cdf2_0fed8c25","line":87,"updated":"2014-06-10 17:15:19.000000000","message":"Any reason that you are not calling the parent\u0027s __init__?","commit_id":"3572f8ce2176daf88633a574adf18a25a169d643"},{"author":{"_account_id":8978,"name":"Marek Denis","email":"marek.denis+openstack@gmail.com","username":"marek-denis"},"change_message_id":"2e99cf0df47ac77a73cd1aa41371f4f8829f6e48","unresolved":false,"context_lines":[{"line_number":84,"context_line":""},{"line_number":85,"context_line":"class CannotScope(ClientException):"},{"line_number":86,"context_line":""},{"line_number":87,"context_line":"    def __init__(self, projects, domains):"},{"line_number":88,"context_line":"        self.projects \u003d projects"},{"line_number":89,"context_line":"        self.domains \u003d domains"}],"source_content_type":"text/x-python","patch_set":15,"id":"1ae5cdf2_e9bf7b5e","line":87,"in_reply_to":"1ae5cdf2_0fed8c25","updated":"2014-06-10 20:27:45.000000000","message":"my bad, fixed.","commit_id":"3572f8ce2176daf88633a574adf18a25a169d643"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"deb1d4e30313deccaefda159c7b5f621406bd21a","unresolved":false,"context_lines":[{"line_number":82,"context_line":"        super(InvalidResponse, self).__init__()"},{"line_number":83,"context_line":"        self.response \u003d response"},{"line_number":84,"context_line":""},{"line_number":85,"context_line":"class ScopingTokenError(ClientException):"},{"line_number":86,"context_line":""},{"line_number":87,"context_line":"    def __init__(self, projects, domains):"},{"line_number":88,"context_line":"        super(ScopingTokenError, self).__init__()"}],"source_content_type":"text/x-python","patch_set":29,"id":"dab895d6_ed752d33","line":85,"updated":"2014-06-29 07:38:01.000000000","message":"this doesn\u0027t seem to be used here, was it meant to be under: https://review.openstack.org/#/c/99704/ ?","commit_id":"24ce620789f878fa78ce34869ab96700c6eb7347"},{"author":{"_account_id":8978,"name":"Marek Denis","email":"marek.denis+openstack@gmail.com","username":"marek-denis"},"change_message_id":"d447283b413e5e8715ef1d6162d08a8135497c7f","unresolved":false,"context_lines":[{"line_number":82,"context_line":"        super(InvalidResponse, self).__init__()"},{"line_number":83,"context_line":"        self.response \u003d response"},{"line_number":84,"context_line":""},{"line_number":85,"context_line":"class ScopingTokenError(ClientException):"},{"line_number":86,"context_line":""},{"line_number":87,"context_line":"    def __init__(self, projects, domains):"},{"line_number":88,"context_line":"        super(ScopingTokenError, self).__init__()"}],"source_content_type":"text/x-python","patch_set":29,"id":"dab895d6_3ce4a73a","line":85,"in_reply_to":"dab895d6_ed752d33","updated":"2014-06-30 10:27:05.000000000","message":"right, i will move it there.","commit_id":"24ce620789f878fa78ce34869ab96700c6eb7347"},{"author":{"_account_id":2218,"name":"Adam Young","email":"adam@younglogic.com","username":"ayoung"},"change_message_id":"8806e4243573d7002d89f63280ad5bd76c0f44cd","unresolved":false,"context_lines":[{"line_number":81,"context_line":"    def __init__(self, response):"},{"line_number":82,"context_line":"        super(InvalidResponse, self).__init__()"},{"line_number":83,"context_line":"        self.response \u003d response"},{"line_number":84,"context_line":""}],"source_content_type":"text/x-python","patch_set":39,"id":"baada198_a1380fd4","line":84,"updated":"2014-07-11 17:33:56.000000000","message":"remove?  Do you need this for pep8?","commit_id":"bfcc5e5d91779e29050336fe1d6152dda0d7d778"},{"author":{"_account_id":8978,"name":"Marek Denis","email":"marek.denis+openstack@gmail.com","username":"marek-denis"},"change_message_id":"f7edfefe66355dcf00dd683c6459aa07e246adee","unresolved":false,"context_lines":[{"line_number":81,"context_line":"    def __init__(self, response):"},{"line_number":82,"context_line":"        super(InvalidResponse, self).__init__()"},{"line_number":83,"context_line":"        self.response \u003d response"},{"line_number":84,"context_line":""}],"source_content_type":"text/x-python","patch_set":39,"id":"baada198_fab70cd6","line":84,"in_reply_to":"baada198_a1380fd4","updated":"2014-07-11 19:15:00.000000000","message":"Done","commit_id":"bfcc5e5d91779e29050336fe1d6152dda0d7d778"}],"keystoneclient/tests/v3/saml2_fixtures.py":[{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"8af25f1bf8514964c32cc0d42045dae35663ee41","unresolved":false,"context_lines":[{"line_number":10,"context_line":"#    License for the specific language governing permissions and limitations"},{"line_number":11,"context_line":"#    under the License."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"SOAP_FAULT \u003d \"\"\""},{"line_number":14,"context_line":"        \u003cS:Envelope xmlns:S\u003d\"http://schemas.xmlsoap.org/soap/envelope/\"\u003e"},{"line_number":15,"context_line":"           \u003cS:Body\u003e"},{"line_number":16,"context_line":"             \u003cS:Fault\u003e"}],"source_content_type":"text/x-python","patch_set":14,"id":"1ae5cdf2_6313915c","line":13,"updated":"2014-06-10 16:15:52.000000000","message":"You probably want all of these XML strings to be bytes. You can do that by prefixing the string with a \u0027b\u0027. For example:\n\n  s \u003d b\"\"\"\n  \"\"\"","commit_id":"e60954df06fcbd176733f1ed9fb2886ac92f9370"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"8af25f1bf8514964c32cc0d42045dae35663ee41","unresolved":false,"context_lines":[{"line_number":23,"context_line":"            \u003c/S:Envelope\u003e"},{"line_number":24,"context_line":"\"\"\""},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"SP_SOAP_RESPONSE \u003d \"\"\"\u003cS:Envelope"},{"line_number":27,"context_line":"xmlns:S\u003d\"http://schemas.xmlsoap.org/soap/envelope/\"\u003e"},{"line_number":28,"context_line":"\u003cS:Header\u003e"},{"line_number":29,"context_line":"\u003cpaos:Request xmlns:paos\u003d\"urn:liberty:paos:2003-08\""}],"source_content_type":"text/x-python","patch_set":14,"id":"1ae5cdf2_c318e577","line":26,"updated":"2014-06-10 16:15:52.000000000","message":"Here too","commit_id":"e60954df06fcbd176733f1ed9fb2886ac92f9370"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"8af25f1bf8514964c32cc0d42045dae35663ee41","unresolved":false,"context_lines":[{"line_number":57,"context_line":" \u003c/samlp:IDPList\u003e\u003c/samlp:Scoping\u003e\u003c/samlp:AuthnRequest\u003e\u003c/S:Body\u003e\u003c/S:Envelope\u003e\"\"\""},{"line_number":58,"context_line":""},{"line_number":59,"context_line":""},{"line_number":60,"context_line":"SAML2_ASSERTION \u003d \"\"\"\u003c?xml version\u003d\"1.0\" encoding\u003d\"UTF-8\"?\u003e"},{"line_number":61,"context_line":"\u003csoap11:Envelope xmlns:soap11\u003d\"http://schemas.xmlsoap.org/soap/envelope/\"\u003e"},{"line_number":62,"context_line":"\u003csoap11:Header\u003e"},{"line_number":63,"context_line":"\u003cecp:Response xmlns:ecp\u003d\"urn:oasis:names:tc:SAML:2.0:profiles:SSO:ecp\""}],"source_content_type":"text/x-python","patch_set":14,"id":"1ae5cdf2_032acd7d","line":60,"updated":"2014-06-10 16:15:52.000000000","message":"Here too","commit_id":"e60954df06fcbd176733f1ed9fb2886ac92f9370"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"deb1d4e30313deccaefda159c7b5f621406bd21a","unresolved":false,"context_lines":[{"line_number":10,"context_line":"#    License for the specific language governing permissions and limitations"},{"line_number":11,"context_line":"#    under the License."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"SOAP_FAULT \u003d b\"\"\""},{"line_number":14,"context_line":"        \u003cS:Envelope xmlns:S\u003d\"http://schemas.xmlsoap.org/soap/envelope/\"\u003e"},{"line_number":15,"context_line":"           \u003cS:Body\u003e"},{"line_number":16,"context_line":"             \u003cS:Fault\u003e"}],"source_content_type":"text/x-python","patch_set":29,"id":"dab895d6_4d945937","line":13,"updated":"2014-06-29 07:38:01.000000000","message":"this isn\u0027t used, also, it\u0027s already defined in saml2.py, line 99","commit_id":"24ce620789f878fa78ce34869ab96700c6eb7347"},{"author":{"_account_id":8978,"name":"Marek Denis","email":"marek.denis+openstack@gmail.com","username":"marek-denis"},"change_message_id":"d447283b413e5e8715ef1d6162d08a8135497c7f","unresolved":false,"context_lines":[{"line_number":10,"context_line":"#    License for the specific language governing permissions and limitations"},{"line_number":11,"context_line":"#    under the License."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"SOAP_FAULT \u003d b\"\"\""},{"line_number":14,"context_line":"        \u003cS:Envelope xmlns:S\u003d\"http://schemas.xmlsoap.org/soap/envelope/\"\u003e"},{"line_number":15,"context_line":"           \u003cS:Body\u003e"},{"line_number":16,"context_line":"             \u003cS:Fault\u003e"}],"source_content_type":"text/x-python","patch_set":29,"id":"dab895d6_01513c62","line":13,"in_reply_to":"dab895d6_4d945937","updated":"2014-06-30 10:27:05.000000000","message":"righty, removed.","commit_id":"24ce620789f878fa78ce34869ab96700c6eb7347"}],"keystoneclient/tests/v3/test_auth_saml2.py":[{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"8af25f1bf8514964c32cc0d42045dae35663ee41","unresolved":false,"context_lines":[{"line_number":65,"context_line":"            username\u003dself.TEST_USER, password\u003dself.TEST_TOKEN,"},{"line_number":66,"context_line":"            project_id\u003dself.TEST_TENANT_ID)"},{"line_number":67,"context_line":""},{"line_number":68,"context_line":"    def simple_http(self, method, url, body\u003dNone, content_type\u003dNone,"},{"line_number":69,"context_line":"                    headers\u003dNone, **kwargs):"},{"line_number":70,"context_line":"        self.stub_url(method, base_url\u003durl, body\u003dbody, headers\u003dheaders,"},{"line_number":71,"context_line":"                      content_type\u003dcontent_type)"}],"source_content_type":"text/x-python","patch_set":14,"id":"1ae5cdf2_d688a124","line":68,"updated":"2014-06-10 16:15:52.000000000","message":"You probably want the body to be string based. I\u0027m not sure why the 2.6 tests work, but the 3.3 test use the body as a string in httpretty.  The httpretty default is a string anyway: https://github.com/gabrielfalcao/HTTPretty/blob/master/httpretty/core.py#L868","commit_id":"e60954df06fcbd176733f1ed9fb2886ac92f9370"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"6b68bacb00777e4dc092efde51c266f63b13a623","unresolved":false,"context_lines":[{"line_number":13,"context_line":"import httpretty"},{"line_number":14,"context_line":"from lxml import etree"},{"line_number":15,"context_line":"import requests"},{"line_number":16,"context_line":"import uuid"},{"line_number":17,"context_line":""},{"line_number":18,"context_line":"from keystoneclient.auth.identity.contrib.federation import saml2"},{"line_number":19,"context_line":"from keystoneclient import exceptions"}],"source_content_type":"text/x-python","patch_set":15,"id":"1ae5cdf2_0fd4ac45","line":16,"updated":"2014-06-10 17:15:19.000000000","message":"uuid is a stdlib module so it should be in the separate section","commit_id":"3572f8ce2176daf88633a574adf18a25a169d643"},{"author":{"_account_id":8978,"name":"Marek Denis","email":"marek.denis+openstack@gmail.com","username":"marek-denis"},"change_message_id":"2e99cf0df47ac77a73cd1aa41371f4f8829f6e48","unresolved":false,"context_lines":[{"line_number":13,"context_line":"import httpretty"},{"line_number":14,"context_line":"from lxml import etree"},{"line_number":15,"context_line":"import requests"},{"line_number":16,"context_line":"import uuid"},{"line_number":17,"context_line":""},{"line_number":18,"context_line":"from keystoneclient.auth.identity.contrib.federation import saml2"},{"line_number":19,"context_line":"from keystoneclient import exceptions"}],"source_content_type":"text/x-python","patch_set":15,"id":"1ae5cdf2_ecbdc9d8","line":16,"in_reply_to":"1ae5cdf2_0fd4ac45","updated":"2014-06-10 20:27:45.000000000","message":"Done","commit_id":"3572f8ce2176daf88633a574adf18a25a169d643"},{"author":{"_account_id":2218,"name":"Adam Young","email":"adam@younglogic.com","username":"ayoung"},"change_message_id":"8806e4243573d7002d89f63280ad5bd76c0f44cd","unresolved":false,"context_lines":[{"line_number":95,"context_line":"    def make_oneline(self, s):"},{"line_number":96,"context_line":"        return etree.tostring(etree.XML(s)).replace(b\u0027\\n\u0027, b\u0027\u0027)"},{"line_number":97,"context_line":""},{"line_number":98,"context_line":"    # TODO(marek-denis): Enable this test"},{"line_number":99,"context_line":"    def conf_params(self):"},{"line_number":100,"context_line":"        section \u003d uuid.uuid4().hex"},{"line_number":101,"context_line":"        identity_provider \u003d uuid.uuid4().hex"}],"source_content_type":"text/x-python","patch_set":39,"id":"baada198_8f2c17ae","line":98,"updated":"2014-07-11 17:33:56.000000000","message":"Explain why this test fails and what the plan is to fix it.","commit_id":"bfcc5e5d91779e29050336fe1d6152dda0d7d778"},{"author":{"_account_id":8978,"name":"Marek Denis","email":"marek.denis+openstack@gmail.com","username":"marek-denis"},"change_message_id":"f7edfefe66355dcf00dd683c6459aa07e246adee","unresolved":false,"context_lines":[{"line_number":95,"context_line":"    def make_oneline(self, s):"},{"line_number":96,"context_line":"        return etree.tostring(etree.XML(s)).replace(b\u0027\\n\u0027, b\u0027\u0027)"},{"line_number":97,"context_line":""},{"line_number":98,"context_line":"    # TODO(marek-denis): Enable this test"},{"line_number":99,"context_line":"    def conf_params(self):"},{"line_number":100,"context_line":"        section \u003d uuid.uuid4().hex"},{"line_number":101,"context_line":"        identity_provider \u003d uuid.uuid4().hex"}],"source_content_type":"text/x-python","patch_set":39,"id":"baada198_7a5f7c41","line":98,"in_reply_to":"baada198_8f2c17ae","updated":"2014-07-11 19:15:00.000000000","message":"Done","commit_id":"bfcc5e5d91779e29050336fe1d6152dda0d7d778"},{"author":{"_account_id":2218,"name":"Adam Young","email":"adam@younglogic.com","username":"ayoung"},"change_message_id":"8806e4243573d7002d89f63280ad5bd76c0f44cd","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":39,"id":"baada198_4f0d9f3d","line":310,"updated":"2014-07-11 17:33:56.000000000","message":"Add end to end flow test.","commit_id":"bfcc5e5d91779e29050336fe1d6152dda0d7d778"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"338404a97552b4aac1a957756fd7a8acb6402736","unresolved":false,"context_lines":[{"line_number":307,"context_line":"            status\u003d200,"},{"line_number":308,"context_line":"            headers\u003d{\u0027X-Subject-Token\u0027: saml2_fixtures.UNSCOPED_TOKEN_HEADER})"},{"line_number":309,"context_line":""},{"line_number":310,"context_line":"        self.session.redirect \u003d False"},{"line_number":311,"context_line":"        response \u003d self.saml2plugin.get_auth_ref(self.session)"},{"line_number":312,"context_line":"        self.assertEqual(saml2_fixtures.UNSCOPED_TOKEN_HEADER,"},{"line_number":313,"context_line":"                         response.auth_token)"}],"source_content_type":"text/x-python","patch_set":40,"id":"baada198_cbe19c2b","line":310,"updated":"2014-07-11 20:42:53.000000000","message":"I think this deserves an inline comment explaining why we are setting this to False in the test.","commit_id":"8f0148b2f7254edf091431a9736820427ae28668"}]}
