)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":10046,"name":"Henrique Truta","email":"henrique@lsd.ufcg.edu.br","username":"henriquetruta"},"change_message_id":"fbfed3a6b69ee280b26ae1fd64fdc60f98b130fb","unresolved":false,"context_lines":[{"line_number":4,"context_line":"Commit:     Tony Wang \u003cwwwjfy@gmail.com\u003e"},{"line_number":5,"context_line":"CommitDate: 2015-11-03 21:37:28 -0500"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"add `type\u0027 filter for list_credentials_for_user"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"When getting, or operating on a credential, EC2 controller need to"},{"line_number":10,"context_line":"specify it\u0027s a ec2 credential, avoiding conflicts with other type of"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":5,"id":"da85f559_745434fe","line":7,"updated":"2015-11-11 16:41:08.000000000","message":"/s/add/Add","commit_id":"6d64d3dcbfda05963a148c28db23ac32e2f7cb50"},{"author":{"_account_id":10046,"name":"Henrique Truta","email":"henrique@lsd.ufcg.edu.br","username":"henriquetruta"},"change_message_id":"fbfed3a6b69ee280b26ae1fd64fdc60f98b130fb","unresolved":false,"context_lines":[{"line_number":6,"context_line":""},{"line_number":7,"context_line":"add `type\u0027 filter for list_credentials_for_user"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"When getting, or operating on a credential, EC2 controller need to"},{"line_number":10,"context_line":"specify it\u0027s a ec2 credential, avoiding conflicts with other type of"},{"line_number":11,"context_line":"credentials."},{"line_number":12,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":5,"id":"da85f559_347f8c67","line":9,"updated":"2015-11-11 16:41:08.000000000","message":"/s/need/needs","commit_id":"6d64d3dcbfda05963a148c28db23ac32e2f7cb50"},{"author":{"_account_id":13063,"name":"WEI CHEN","email":"dave.jungler@gmail.com","username":"wei.d.chen"},"change_message_id":"692124819211a7cbaeb6e5ecee37802f9c9a246d","unresolved":false,"context_lines":[{"line_number":4,"context_line":"Commit:     Tony Wang \u003cwwwjfy@gmail.com\u003e"},{"line_number":5,"context_line":"CommitDate: 2015-12-11 01:02:38 -0500"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Add `type\u0027 filter for list_credentials_for_user"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"When getting, or operating on a credential, EC2 controller needs to"},{"line_number":10,"context_line":"specify it\u0027s a ec2 credential, avoiding conflicts with other type of"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":9,"id":"5a710552_46167df2","line":7,"updated":"2015-12-16 04:47:13.000000000","message":"change to `type`, fine as it is.","commit_id":"9fc1cc67d993cfa0afc46aaea2802e1c35445f77"}],"keystone/contrib/ec2/controllers.py":[{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"35c054df6ce2ad235dca281e55b9637e6dc14f0b","unresolved":false,"context_lines":[{"line_number":245,"context_line":"                \u0027secret\u0027: blob.get(\u0027secret\u0027),"},{"line_number":246,"context_line":"                \u0027trust_id\u0027: blob.get(\u0027trust_id\u0027)}"},{"line_number":247,"context_line":""},{"line_number":248,"context_line":"    def _get_credentials(self, credential_id):"},{"line_number":249,"context_line":"        \"\"\"Return credentials from an ID."},{"line_number":250,"context_line":""},{"line_number":251,"context_line":"        :param credential_id: id of credential"}],"source_content_type":"text/x-python","patch_set":2,"id":"5a2ca52d_e773cf7e","line":248,"updated":"2015-10-15 14:30:39.000000000","message":"feel free to put up another patch that renames this to:\n\n  _get_credential\n\nit only retrieves one, so keep it singular","commit_id":"f8017ad7eda700a4049943ca34648514a32e27dd"},{"author":{"_account_id":17123,"name":"Tom Cocozzello (tjcocozz)","email":"tjcocozz@us.ibm.com","username":"tcocozzello"},"change_message_id":"a4c8a4715f9781a106e0e0d6aaae9a4353bd74e8","unresolved":false,"context_lines":[{"line_number":225,"context_line":"        \"\"\""},{"line_number":226,"context_line":""},{"line_number":227,"context_line":"        self.identity_api.get_user(user_id)"},{"line_number":228,"context_line":"        self._get_credential(credential_id)"},{"line_number":229,"context_line":"        ec2_credential_id \u003d utils.hash_access_key(credential_id)"},{"line_number":230,"context_line":"        return self.credential_api.delete_credential(ec2_credential_id)"},{"line_number":231,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"3a29b11f_44b0cff4","line":228,"updated":"2015-10-19 15:48:28.000000000","message":"I\u0027m not trying to be a stickler but this isn\u0027t related to this patch.  Could you make another patch for this change?","commit_id":"bf52fdf43f45afffb4c180c8a4c6621b99151c98"},{"author":{"_account_id":14413,"name":"Tony Wang","username":"tony","inactive":true},"change_message_id":"7907097b462ef175ce57cca339aa951c0fdc2db2","unresolved":false,"context_lines":[{"line_number":225,"context_line":"        \"\"\""},{"line_number":226,"context_line":""},{"line_number":227,"context_line":"        self.identity_api.get_user(user_id)"},{"line_number":228,"context_line":"        self._get_credential(credential_id)"},{"line_number":229,"context_line":"        ec2_credential_id \u003d utils.hash_access_key(credential_id)"},{"line_number":230,"context_line":"        return self.credential_api.delete_credential(ec2_credential_id)"},{"line_number":231,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"3a29b11f_440d283d","line":228,"in_reply_to":"3a29b11f_24d90c22","updated":"2015-10-19 16:21:43.000000000","message":"I\u0027d love to follow conventions of community, but I think there won\u0027t be strong objection about correcting typo along with other changes in one commit.\nIt\u0027s also from another reviewer\u0027s comment.\nI\u0027m not sure internal function renaming need to be in commit message, I\u0027ll think about it, and see what other reviewers think.","commit_id":"bf52fdf43f45afffb4c180c8a4c6621b99151c98"},{"author":{"_account_id":14413,"name":"Tony Wang","username":"tony","inactive":true},"change_message_id":"7bfe796c1081da5aced6dd94b70e3af420b1277c","unresolved":false,"context_lines":[{"line_number":225,"context_line":"        \"\"\""},{"line_number":226,"context_line":""},{"line_number":227,"context_line":"        self.identity_api.get_user(user_id)"},{"line_number":228,"context_line":"        self._get_credential(credential_id)"},{"line_number":229,"context_line":"        ec2_credential_id \u003d utils.hash_access_key(credential_id)"},{"line_number":230,"context_line":"        return self.credential_api.delete_credential(ec2_credential_id)"},{"line_number":231,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"3a29b11f_d9bb61c3","line":228,"in_reply_to":"3a29b11f_44b0cff4","updated":"2015-10-19 16:00:32.000000000","message":"I know it\u0027s good to have different commits for different things, but for some related typos, I think it\u0027s fine to there aren\u0027t many, to be included in one patch.","commit_id":"bf52fdf43f45afffb4c180c8a4c6621b99151c98"},{"author":{"_account_id":17123,"name":"Tom Cocozzello (tjcocozz)","email":"tjcocozz@us.ibm.com","username":"tcocozzello"},"change_message_id":"9154746c6e35cf2daf376ce7c93977c1a4c37947","unresolved":false,"context_lines":[{"line_number":225,"context_line":"        \"\"\""},{"line_number":226,"context_line":""},{"line_number":227,"context_line":"        self.identity_api.get_user(user_id)"},{"line_number":228,"context_line":"        self._get_credential(credential_id)"},{"line_number":229,"context_line":"        ec2_credential_id \u003d utils.hash_access_key(credential_id)"},{"line_number":230,"context_line":"        return self.credential_api.delete_credential(ec2_credential_id)"},{"line_number":231,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"3a29b11f_24d90c22","line":228,"in_reply_to":"3a29b11f_d9bb61c3","updated":"2015-10-19 16:09:29.000000000","message":"I think there are many people in the community that are willing to argue the opposite.  I am fine with what you have here since it needs to be done, just make sure to put what you are doing here in your commit message.","commit_id":"bf52fdf43f45afffb4c180c8a4c6621b99151c98"},{"author":{"_account_id":10046,"name":"Henrique Truta","email":"henrique@lsd.ufcg.edu.br","username":"henriquetruta"},"change_message_id":"2c02e3c5e56b7d5106e86daedb3242997ac7b9b9","unresolved":false,"context_lines":[{"line_number":53,"context_line":"                     \u0027token_provider_api\u0027)"},{"line_number":54,"context_line":"@six.add_metaclass(abc.ABCMeta)"},{"line_number":55,"context_line":"class Ec2ControllerCommon(object):"},{"line_number":56,"context_line":"    def check_signature(self, cred_ref, credentials):"},{"line_number":57,"context_line":"        signer \u003d ec2_utils.Ec2Signer(cred_ref[\u0027secret\u0027])"},{"line_number":58,"context_line":"        signature \u003d signer.generate(credentials)"},{"line_number":59,"context_line":"        # NOTE(davechen): credentials.get(\u0027signature\u0027) is not guaranteed to"}],"source_content_type":"text/x-python","patch_set":5,"id":"da85f559_517b42f5","line":56,"updated":"2015-11-11 16:40:03.000000000","message":"looks like this refactoring has nothing to do with the purpose of the patch","commit_id":"6d64d3dcbfda05963a148c28db23ac32e2f7cb50"},{"author":{"_account_id":14413,"name":"Tony Wang","username":"tony","inactive":true},"change_message_id":"290606617e17b7bc6f18c65abd3aa5719588f4a5","unresolved":false,"context_lines":[{"line_number":53,"context_line":"                     \u0027token_provider_api\u0027)"},{"line_number":54,"context_line":"@six.add_metaclass(abc.ABCMeta)"},{"line_number":55,"context_line":"class Ec2ControllerCommon(object):"},{"line_number":56,"context_line":"    def check_signature(self, cred_ref, credentials):"},{"line_number":57,"context_line":"        signer \u003d ec2_utils.Ec2Signer(cred_ref[\u0027secret\u0027])"},{"line_number":58,"context_line":"        signature \u003d signer.generate(credentials)"},{"line_number":59,"context_line":"        # NOTE(davechen): credentials.get(\u0027signature\u0027) is not guaranteed to"}],"source_content_type":"text/x-python","patch_set":5,"id":"ba8a016a_a1fe8136","line":56,"in_reply_to":"ba8a016a_0cf1e16a","updated":"2015-11-20 15:06:14.000000000","message":"I really think those renaming is not worth committing a separate patch set, even mentioning in commit message.\n\nBut OK, I\u0027ll add in commit message.","commit_id":"6d64d3dcbfda05963a148c28db23ac32e2f7cb50"},{"author":{"_account_id":14413,"name":"Tony Wang","username":"tony","inactive":true},"change_message_id":"c54da1beb7001a1215c85d8516eb5aca0fe63706","unresolved":false,"context_lines":[{"line_number":53,"context_line":"                     \u0027token_provider_api\u0027)"},{"line_number":54,"context_line":"@six.add_metaclass(abc.ABCMeta)"},{"line_number":55,"context_line":"class Ec2ControllerCommon(object):"},{"line_number":56,"context_line":"    def check_signature(self, cred_ref, credentials):"},{"line_number":57,"context_line":"        signer \u003d ec2_utils.Ec2Signer(cred_ref[\u0027secret\u0027])"},{"line_number":58,"context_line":"        signature \u003d signer.generate(credentials)"},{"line_number":59,"context_line":"        # NOTE(davechen): credentials.get(\u0027signature\u0027) is not guaranteed to"}],"source_content_type":"text/x-python","patch_set":5,"id":"da85f559_d81e5c6f","line":56,"in_reply_to":"da85f559_517b42f5","updated":"2015-11-12 01:57:04.000000000","message":"I think internal renaming (inside a method) wouldn\u0027t break compatibility or be a problem when this commit needs to be reverted. It\u0027s kind of like fixing typos.\nThat being said, if more reviewers think this need to be in a separate commit, I\u0027ll do that.","commit_id":"6d64d3dcbfda05963a148c28db23ac32e2f7cb50"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"23912d33181e9015c1f433582054e7a8b2e260af","unresolved":false,"context_lines":[{"line_number":53,"context_line":"                     \u0027token_provider_api\u0027)"},{"line_number":54,"context_line":"@six.add_metaclass(abc.ABCMeta)"},{"line_number":55,"context_line":"class Ec2ControllerCommon(object):"},{"line_number":56,"context_line":"    def check_signature(self, cred_ref, credentials):"},{"line_number":57,"context_line":"        signer \u003d ec2_utils.Ec2Signer(cred_ref[\u0027secret\u0027])"},{"line_number":58,"context_line":"        signature \u003d signer.generate(credentials)"},{"line_number":59,"context_line":"        # NOTE(davechen): credentials.get(\u0027signature\u0027) is not guaranteed to"}],"source_content_type":"text/x-python","patch_set":5,"id":"ba8a016a_0cf1e16a","line":56,"in_reply_to":"da85f559_d81e5c6f","updated":"2015-11-20 02:57:34.000000000","message":"As there are several unrelated fixes at this file, I think having a separate patch for them would be better, as it make life easier for reviews, because we will only see what this patch is really supposed to do.\n\nAn alternative is to make clear in the commit message that you are fixing typos, etc","commit_id":"6d64d3dcbfda05963a148c28db23ac32e2f7cb50"},{"author":{"_account_id":11428,"name":"Ajaya Agrawal","email":"ajku.agr@gmail.com","username":"ajayaa"},"change_message_id":"3ea4bf78343d3d0669e258cf231423eac46419d9","unresolved":false,"context_lines":[{"line_number":252,"context_line":"        \"\"\""},{"line_number":253,"context_line":"        ec2_credential_id \u003d utils.hash_access_key(credential_id)"},{"line_number":254,"context_line":"        cred \u003d self.credential_api.get_credential(ec2_credential_id)"},{"line_number":255,"context_line":"        if not cred or cred[\u0027type\u0027] !\u003d \u0027ec2\u0027:"},{"line_number":256,"context_line":"            raise exception.Unauthorized("},{"line_number":257,"context_line":"                message\u003d_(\u0027EC2 access key not found.\u0027))"},{"line_number":258,"context_line":"        return self._convert_v3_to_ec2_credential(cred)"}],"source_content_type":"text/x-python","patch_set":5,"id":"fa80f949_d8380c40","line":255,"updated":"2015-11-05 08:03:56.000000000","message":"Do we need the check \"if not cred\" ? While I am aware this is not related to your change, I think it\u0027s a good idea to remove redundant checks.\n\nPlease see\nhttps://github.com/openstack/keystone/blob/master/keystone/credential/backends/sql.py#L60\n\n_get_credential already checks for None.","commit_id":"6d64d3dcbfda05963a148c28db23ac32e2f7cb50"},{"author":{"_account_id":10046,"name":"Henrique Truta","email":"henrique@lsd.ufcg.edu.br","username":"henriquetruta"},"change_message_id":"2c02e3c5e56b7d5106e86daedb3242997ac7b9b9","unresolved":false,"context_lines":[{"line_number":252,"context_line":"        \"\"\""},{"line_number":253,"context_line":"        ec2_credential_id \u003d utils.hash_access_key(credential_id)"},{"line_number":254,"context_line":"        cred \u003d self.credential_api.get_credential(ec2_credential_id)"},{"line_number":255,"context_line":"        if not cred or cred[\u0027type\u0027] !\u003d \u0027ec2\u0027:"},{"line_number":256,"context_line":"            raise exception.Unauthorized("},{"line_number":257,"context_line":"                message\u003d_(\u0027EC2 access key not found.\u0027))"},{"line_number":258,"context_line":"        return self._convert_v3_to_ec2_credential(cred)"}],"source_content_type":"text/x-python","patch_set":5,"id":"da85f559_b1e06e97","line":255,"in_reply_to":"fa80f949_d8380c40","updated":"2015-11-11 16:40:03.000000000","message":"agreed. I\u0027d do this whole refactoring in a separate patch","commit_id":"6d64d3dcbfda05963a148c28db23ac32e2f7cb50"},{"author":{"_account_id":11428,"name":"Ajaya Agrawal","email":"ajku.agr@gmail.com","username":"ajayaa"},"change_message_id":"3ea4bf78343d3d0669e258cf231423eac46419d9","unresolved":false,"context_lines":[{"line_number":254,"context_line":"        cred \u003d self.credential_api.get_credential(ec2_credential_id)"},{"line_number":255,"context_line":"        if not cred or cred[\u0027type\u0027] !\u003d \u0027ec2\u0027:"},{"line_number":256,"context_line":"            raise exception.Unauthorized("},{"line_number":257,"context_line":"                message\u003d_(\u0027EC2 access key not found.\u0027))"},{"line_number":258,"context_line":"        return self._convert_v3_to_ec2_credential(cred)"},{"line_number":259,"context_line":""},{"line_number":260,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"fa80f949_7827a012","line":257,"updated":"2015-11-05 08:03:56.000000000","message":"Should this exception not be exception.CredentialNotFound instead of exception.Unauthorized()?\n\nAgain not related to your change but if we agree on changing this then I would raise a new patch.","commit_id":"6d64d3dcbfda05963a148c28db23ac32e2f7cb50"},{"author":{"_account_id":14413,"name":"Tony Wang","username":"tony","inactive":true},"change_message_id":"472757f2de5fc0f2760044e22ca6e2a4960922f4","unresolved":false,"context_lines":[{"line_number":254,"context_line":"        cred \u003d self.credential_api.get_credential(ec2_credential_id)"},{"line_number":255,"context_line":"        if not cred or cred[\u0027type\u0027] !\u003d \u0027ec2\u0027:"},{"line_number":256,"context_line":"            raise exception.Unauthorized("},{"line_number":257,"context_line":"                message\u003d_(\u0027EC2 access key not found.\u0027))"},{"line_number":258,"context_line":"        return self._convert_v3_to_ec2_credential(cred)"},{"line_number":259,"context_line":""},{"line_number":260,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"fa80f949_1393d550","line":257,"in_reply_to":"fa80f949_7827a012","updated":"2015-11-05 08:28:25.000000000","message":"I can see it\u0027s for security. Keystone should not reveal if the access doesn\u0027t exist or access/secret don\u0027t match.\nWhen _check_credential_owner_and_user_id_match does the check for get and list, authenticate needs Unauthorized raised.\n\nAnd you\u0027re right that it won\u0027t work because credential api already raises a not found exception.\n\nI think the reasonable behavior is to raise different exceptions in different scenarios, and since multiple places need to be changed, and tests need to be added, I think a separate patch set is better, to handle this problem.","commit_id":"6d64d3dcbfda05963a148c28db23ac32e2f7cb50"},{"author":{"_account_id":17123,"name":"Tom Cocozzello (tjcocozz)","email":"tjcocozz@us.ibm.com","username":"tcocozzello"},"change_message_id":"b989a2dc877198c116bbc5304d22c98f7ed19d6c","unresolved":false,"context_lines":[{"line_number":17,"context_line":"This service allows the creation of access/secret credentials used for"},{"line_number":18,"context_line":"the ec2 interop layer of OpenStack."},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"A user can create as many access/secret pairs, each of which mapped to a"},{"line_number":21,"context_line":"specific project.  This is required because OpenStack supports a user"},{"line_number":22,"context_line":"belonging to multiple projects, whereas the signatures created on ec2-style"},{"line_number":23,"context_line":"requests don\u0027t allow specification of which project the user wishes to act"}],"source_content_type":"text/x-python","patch_set":6,"id":"ba8a016a_f80d0ce9","line":20,"updated":"2015-11-20 20:16:44.000000000","message":"i recommend changing this back","commit_id":"920ff6dd94546acd400210f7eb5133b9229424bf"},{"author":{"_account_id":13063,"name":"WEI CHEN","email":"dave.jungler@gmail.com","username":"wei.d.chen"},"change_message_id":"4e64d9a08768547ac2b9d0b070df384ceb37d593","unresolved":false,"context_lines":[{"line_number":17,"context_line":"This service allows the creation of access/secret credentials used for"},{"line_number":18,"context_line":"the ec2 interop layer of OpenStack."},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"A user can create as many access/secret pairs, each of which mapped to a"},{"line_number":21,"context_line":"specific project.  This is required because OpenStack supports a user"},{"line_number":22,"context_line":"belonging to multiple projects, whereas the signatures created on ec2-style"},{"line_number":23,"context_line":"requests don\u0027t allow specification of which project the user wishes to act"}],"source_content_type":"text/x-python","patch_set":6,"id":"ba8a016a_11feb405","line":20,"updated":"2015-11-20 22:04:35.000000000","message":"if you want to change, maybe change to \"is mapped\"?","commit_id":"920ff6dd94546acd400210f7eb5133b9229424bf"},{"author":{"_account_id":13063,"name":"WEI CHEN","email":"dave.jungler@gmail.com","username":"wei.d.chen"},"change_message_id":"4e64d9a08768547ac2b9d0b070df384ceb37d593","unresolved":false,"context_lines":[{"line_number":53,"context_line":"                     \u0027token_provider_api\u0027)"},{"line_number":54,"context_line":"@six.add_metaclass(abc.ABCMeta)"},{"line_number":55,"context_line":"class Ec2ControllerCommon(object):"},{"line_number":56,"context_line":"    def check_signature(self, cred_ref, credentials):"},{"line_number":57,"context_line":"        signer \u003d ec2_utils.Ec2Signer(cred_ref[\u0027secret\u0027])"},{"line_number":58,"context_line":"        signature \u003d signer.generate(credentials)"},{"line_number":59,"context_line":"        # NOTE(davechen): credentials.get(\u0027signature\u0027) is not guaranteed to"}],"source_content_type":"text/x-python","patch_set":6,"id":"ba8a016a_51b8bc2a","line":56,"updated":"2015-11-20 22:04:35.000000000","message":"I think it\u0027s just the abbreviation of \"credentials reference\", but looks like a right change.","commit_id":"920ff6dd94546acd400210f7eb5133b9229424bf"},{"author":{"_account_id":13063,"name":"WEI CHEN","email":"dave.jungler@gmail.com","username":"wei.d.chen"},"change_message_id":"4e64d9a08768547ac2b9d0b070df384ceb37d593","unresolved":false,"context_lines":[{"line_number":196,"context_line":"        \"\"\""},{"line_number":197,"context_line":"        self.identity_api.get_user(user_id)"},{"line_number":198,"context_line":"        credential_refs \u003d self.credential_api.list_credentials_for_user("},{"line_number":199,"context_line":"            user_id, type\u003d\u0027ec2\u0027)"},{"line_number":200,"context_line":"        return {\u0027credentials\u0027:"},{"line_number":201,"context_line":"                [self._convert_v3_to_ec2_credential(credential)"},{"line_number":202,"context_line":"                 for credential in credential_refs]}"}],"source_content_type":"text/x-python","patch_set":6,"id":"ba8a016a_0fa0c58f","line":199,"updated":"2015-11-20 22:04:35.000000000","message":"better to define a constant, and use the constant instead of the hard coded value.","commit_id":"920ff6dd94546acd400210f7eb5133b9229424bf"},{"author":{"_account_id":13063,"name":"WEI CHEN","email":"dave.jungler@gmail.com","username":"wei.d.chen"},"change_message_id":"4e64d9a08768547ac2b9d0b070df384ceb37d593","unresolved":false,"context_lines":[{"line_number":243,"context_line":"                \u0027secret\u0027: blob.get(\u0027secret\u0027),"},{"line_number":244,"context_line":"                \u0027trust_id\u0027: blob.get(\u0027trust_id\u0027)}"},{"line_number":245,"context_line":""},{"line_number":246,"context_line":"    def _get_credential(self, credential_id):"},{"line_number":247,"context_line":"        \"\"\"Return credentials from an ID."},{"line_number":248,"context_line":""},{"line_number":249,"context_line":"        :param credential_id: id of credential"}],"source_content_type":"text/x-python","patch_set":6,"id":"ba8a016a_f22444c7","line":246,"updated":"2015-11-20 22:04:35.000000000","message":"These change also impact v2 APIs, but they are not tested, happy to see you also add the testcases for V2 API.\n\nI think it\u0027s should not work correctly without this patch for V2 API as well, this patch fix it and thus, some testcase there should be good.\n\nThe file you may refer to is here: https://github.com/openstack/keystone/blob/master/keystone/tests/unit/test_contrib_ec2.py","commit_id":"920ff6dd94546acd400210f7eb5133b9229424bf"},{"author":{"_account_id":17123,"name":"Tom Cocozzello (tjcocozz)","email":"tjcocozz@us.ibm.com","username":"tcocozzello"},"change_message_id":"b989a2dc877198c116bbc5304d22c98f7ed19d6c","unresolved":false,"context_lines":[{"line_number":247,"context_line":"        \"\"\"Return credentials from an ID."},{"line_number":248,"context_line":""},{"line_number":249,"context_line":"        :param credential_id: id of credential"},{"line_number":250,"context_line":"        :raises exception.Unauthorized: when credential id is invalid"},{"line_number":251,"context_line":"        :returns: credential: dict of ec2 credential."},{"line_number":252,"context_line":"        \"\"\""},{"line_number":253,"context_line":"        ec2_credential_id \u003d utils.hash_access_key(credential_id)"}],"source_content_type":"text/x-python","patch_set":6,"id":"ba8a016a_d89fe84e","line":250,"updated":"2015-11-20 20:16:44.000000000","message":"add to this  \"or when the credential type is not ec2 \"","commit_id":"920ff6dd94546acd400210f7eb5133b9229424bf"},{"author":{"_account_id":17123,"name":"Tom Cocozzello (tjcocozz)","email":"tjcocozz@us.ibm.com","username":"tcocozzello"},"change_message_id":"b989a2dc877198c116bbc5304d22c98f7ed19d6c","unresolved":false,"context_lines":[{"line_number":252,"context_line":"        \"\"\""},{"line_number":253,"context_line":"        ec2_credential_id \u003d utils.hash_access_key(credential_id)"},{"line_number":254,"context_line":"        cred \u003d self.credential_api.get_credential(ec2_credential_id)"},{"line_number":255,"context_line":"        if not cred or cred[\u0027type\u0027] !\u003d \u0027ec2\u0027:"},{"line_number":256,"context_line":"            raise exception.Unauthorized("},{"line_number":257,"context_line":"                message\u003d_(\u0027EC2 access key not found.\u0027))"},{"line_number":258,"context_line":"        return self._convert_v3_to_ec2_credential(cred)"}],"source_content_type":"text/x-python","patch_set":6,"id":"ba8a016a_d3cd895e","line":255,"updated":"2015-11-20 20:16:44.000000000","message":"I got a question here.   So to my understanding \u0027type\u0027 is part of the v3 token as per the bug where you say \u0027New credentials created by EC2 extension are with the \"type\" property\u0027\n\nI don\u0027t understand how a v2 token can come in here without at \u0027type\u0027 property and not fail?\n\n- Can someone point me to the doc explaining ec2 v2 credentials with keystone?\n\n- If all ec2 credentials have the \"type\" property maybe the bug should be updated.","commit_id":"920ff6dd94546acd400210f7eb5133b9229424bf"},{"author":{"_account_id":13063,"name":"WEI CHEN","email":"dave.jungler@gmail.com","username":"wei.d.chen"},"change_message_id":"4e64d9a08768547ac2b9d0b070df384ceb37d593","unresolved":false,"context_lines":[{"line_number":252,"context_line":"        \"\"\""},{"line_number":253,"context_line":"        ec2_credential_id \u003d utils.hash_access_key(credential_id)"},{"line_number":254,"context_line":"        cred \u003d self.credential_api.get_credential(ec2_credential_id)"},{"line_number":255,"context_line":"        if not cred or cred[\u0027type\u0027] !\u003d \u0027ec2\u0027:"},{"line_number":256,"context_line":"            raise exception.Unauthorized("},{"line_number":257,"context_line":"                message\u003d_(\u0027EC2 access key not found.\u0027))"},{"line_number":258,"context_line":"        return self._convert_v3_to_ec2_credential(cred)"}],"source_content_type":"text/x-python","patch_set":6,"id":"ba8a016a_ef3ea128","line":255,"in_reply_to":"ba8a016a_d3cd895e","updated":"2015-11-20 22:04:35.000000000","message":"Tom -  ec2 credentials did has \"type\", currently, we have two types of credentials, \"ec2\" and \"cert\", it\u0027s not relevant with v2/v3.\n\nFor the rest of your question, sorry, I didn\u0027t get it. IIRC, the docs for ec2 v2 credentials has not been documented well in keystone.","commit_id":"920ff6dd94546acd400210f7eb5133b9229424bf"},{"author":{"_account_id":17123,"name":"Tom Cocozzello (tjcocozz)","email":"tjcocozz@us.ibm.com","username":"tcocozzello"},"change_message_id":"63cd430463369c6b2f82cb3ee72787691cae9e18","unresolved":false,"context_lines":[{"line_number":252,"context_line":"        \"\"\""},{"line_number":253,"context_line":"        ec2_credential_id \u003d utils.hash_access_key(credential_id)"},{"line_number":254,"context_line":"        cred \u003d self.credential_api.get_credential(ec2_credential_id)"},{"line_number":255,"context_line":"        if not cred or cred[\u0027type\u0027] !\u003d \u0027ec2\u0027:"},{"line_number":256,"context_line":"            raise exception.Unauthorized("},{"line_number":257,"context_line":"                message\u003d_(\u0027EC2 access key not found.\u0027))"},{"line_number":258,"context_line":"        return self._convert_v3_to_ec2_credential(cred)"}],"source_content_type":"text/x-python","patch_set":6,"id":"ba8a016a_6be7c812","line":255,"in_reply_to":"ba8a016a_ef3ea128","updated":"2015-11-23 16:14:52.000000000","message":"Dave thanks for the update. Its good to know the docs are out there, just need to find them. :)","commit_id":"920ff6dd94546acd400210f7eb5133b9229424bf"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"3141c5debe7f8776d318da3a6004bac2765da32c","unresolved":false,"context_lines":[{"line_number":201,"context_line":"            user_id, type\u003dCRED_TYPE_EC2)"},{"line_number":202,"context_line":"        return {\u0027credentials\u0027:"},{"line_number":203,"context_line":"                [self._convert_v3_to_ec2_credential(credential)"},{"line_number":204,"context_line":"                 for credential in credential_refs]}"},{"line_number":205,"context_line":""},{"line_number":206,"context_line":"    def get_credential(self, user_id, credential_id):"},{"line_number":207,"context_line":"        \"\"\"Retrieve a user\u0027s access/secret pair by the access key."}],"source_content_type":"text/x-python","patch_set":7,"id":"9a8ffd7b_e8cc938a","line":204,"updated":"2015-11-29 17:27:07.000000000","message":"unnecessary change","commit_id":"e9336929835a21cf5b6f83c2fac78b4356ad478b"},{"author":{"_account_id":13063,"name":"WEI CHEN","email":"dave.jungler@gmail.com","username":"wei.d.chen"},"change_message_id":"a9931ef43b0d3792ea5256c01f4fcc52ecbe4b12","unresolved":false,"context_lines":[{"line_number":245,"context_line":"                \u0027secret\u0027: blob.get(\u0027secret\u0027),"},{"line_number":246,"context_line":"                \u0027trust_id\u0027: blob.get(\u0027trust_id\u0027)}"},{"line_number":247,"context_line":""},{"line_number":248,"context_line":"    def _get_credential(self, credential_id):"},{"line_number":249,"context_line":"        \"\"\"Return credentials from an ID."},{"line_number":250,"context_line":""},{"line_number":251,"context_line":"        :param credential_id: id of credential"}],"source_content_type":"text/x-python","patch_set":7,"id":"9a8ffd7b_7c994478","line":248,"updated":"2015-11-29 20:26:20.000000000","message":"suggest to revert back all of these changes to focus on the real issue you want to address in this patch.\n\nall of these spelling changes could be addressed in another patch if really needed.","commit_id":"e9336929835a21cf5b6f83c2fac78b4356ad478b"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"c850819f674476247e310475f5b7004908121c25","unresolved":false,"context_lines":[{"line_number":46,"context_line":"from keystone.common import wsgi"},{"line_number":47,"context_line":"from keystone import exception"},{"line_number":48,"context_line":"from keystone.i18n import _"},{"line_number":49,"context_line":""},{"line_number":50,"context_line":"CRED_TYPE_EC2 \u003d \u0027ec2\u0027"},{"line_number":51,"context_line":""},{"line_number":52,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"fa69d971_68e65845","line":49,"updated":"2016-01-06 22:23:37.000000000","message":"(nit) missing a newline -\u003e http://docs.openstack.org/developer/hacking/#import-order-template","commit_id":"9fc1cc67d993cfa0afc46aaea2802e1c35445f77"}],"keystone/credential/backends/sql.py":[{"author":{"_account_id":17123,"name":"Tom Cocozzello (tjcocozz)","email":"tjcocozz@us.ibm.com","username":"tcocozzello"},"change_message_id":"a4c8a4715f9781a106e0e0d6aaae9a4353bd74e8","unresolved":false,"context_lines":[{"line_number":54,"context_line":"        query \u003d session.query(CredentialModel)"},{"line_number":55,"context_line":"        query \u003d query.filter_by(user_id\u003duser_id)"},{"line_number":56,"context_line":"        if type:"},{"line_number":57,"context_line":"            query \u003d query.filter_by(type\u003dtype)"},{"line_number":58,"context_line":"        refs \u003d query.all()"},{"line_number":59,"context_line":"        return [ref.to_dict() for ref in refs]"},{"line_number":60,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"3a29b11f_be2c4b4b","line":57,"updated":"2015-10-19 15:48:28.000000000","message":"It looks like you are doing two filters in the same function if someone specifies the type.  To make 1 filter you can do this: \n \nif type:\n    query \u003d query.filter_by(user_id\u003duser_id, type\u003dtype)\nelse:\n    query \u003d query.filter_by(user_id\u003duser_id)\n\n\ninstead of the above 3 lines.","commit_id":"bf52fdf43f45afffb4c180c8a4c6621b99151c98"},{"author":{"_account_id":14413,"name":"Tony Wang","username":"tony","inactive":true},"change_message_id":"7907097b462ef175ce57cca339aa951c0fdc2db2","unresolved":false,"context_lines":[{"line_number":54,"context_line":"        query \u003d session.query(CredentialModel)"},{"line_number":55,"context_line":"        query \u003d query.filter_by(user_id\u003duser_id)"},{"line_number":56,"context_line":"        if type:"},{"line_number":57,"context_line":"            query \u003d query.filter_by(type\u003dtype)"},{"line_number":58,"context_line":"        refs \u003d query.all()"},{"line_number":59,"context_line":"        return [ref.to_dict() for ref in refs]"},{"line_number":60,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"3a29b11f_ff6cfd9d","line":57,"in_reply_to":"3a29b11f_4473e880","updated":"2015-10-19 16:21:43.000000000","message":"That\u0027s actually what SQLAlchemy do. When you call like methods like all(), the SQL will be built and actually executed.\nDefinitely it won\u0027t get all results from database and do filtering in Python. Sorry I\u0027m not convenient browsing and looking for documents now, but you may check other sql related code, like assignment/backend/sql.py, etc","commit_id":"bf52fdf43f45afffb4c180c8a4c6621b99151c98"},{"author":{"_account_id":17123,"name":"Tom Cocozzello (tjcocozz)","email":"tjcocozz@us.ibm.com","username":"tcocozzello"},"change_message_id":"9154746c6e35cf2daf376ce7c93977c1a4c37947","unresolved":false,"context_lines":[{"line_number":54,"context_line":"        query \u003d session.query(CredentialModel)"},{"line_number":55,"context_line":"        query \u003d query.filter_by(user_id\u003duser_id)"},{"line_number":56,"context_line":"        if type:"},{"line_number":57,"context_line":"            query \u003d query.filter_by(type\u003dtype)"},{"line_number":58,"context_line":"        refs \u003d query.all()"},{"line_number":59,"context_line":"        return [ref.to_dict() for ref in refs]"},{"line_number":60,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"3a29b11f_4473e880","line":57,"in_reply_to":"3a29b11f_5924310c","updated":"2015-10-19 16:09:29.000000000","message":"That\u0027s really cool.  I did a quick google for it and could not find it anywhere. Do you have a good doc that references that?","commit_id":"bf52fdf43f45afffb4c180c8a4c6621b99151c98"},{"author":{"_account_id":14413,"name":"Tony Wang","username":"tony","inactive":true},"change_message_id":"7bfe796c1081da5aced6dd94b70e3af420b1277c","unresolved":false,"context_lines":[{"line_number":54,"context_line":"        query \u003d session.query(CredentialModel)"},{"line_number":55,"context_line":"        query \u003d query.filter_by(user_id\u003duser_id)"},{"line_number":56,"context_line":"        if type:"},{"line_number":57,"context_line":"            query \u003d query.filter_by(type\u003dtype)"},{"line_number":58,"context_line":"        refs \u003d query.all()"},{"line_number":59,"context_line":"        return [ref.to_dict() for ref in refs]"},{"line_number":60,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"3a29b11f_5924310c","line":57,"in_reply_to":"3a29b11f_be2c4b4b","updated":"2015-10-19 16:00:32.000000000","message":"it\u0027s actually not two filters. SQLAlchemy will combine the two \"filter_by\"s to be one sql statement","commit_id":"bf52fdf43f45afffb4c180c8a4c6621b99151c98"},{"author":{"_account_id":17123,"name":"Tom Cocozzello (tjcocozz)","email":"tjcocozz@us.ibm.com","username":"tcocozzello"},"change_message_id":"bac0cf4ae5b11218ec7dff1415796e9316b184a4","unresolved":false,"context_lines":[{"line_number":54,"context_line":"        query \u003d session.query(CredentialModel)"},{"line_number":55,"context_line":"        query \u003d query.filter_by(user_id\u003duser_id)"},{"line_number":56,"context_line":"        if type:"},{"line_number":57,"context_line":"            query \u003d query.filter_by(type\u003dtype)"},{"line_number":58,"context_line":"        refs \u003d query.all()"},{"line_number":59,"context_line":"        return [ref.to_dict() for ref in refs]"},{"line_number":60,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"3a29b11f_f1b9912f","line":57,"in_reply_to":"3a29b11f_ff6cfd9d","updated":"2015-10-19 16:46:49.000000000","message":"Thank you, Looking into this further, that is exactly what happens.  Thank you for clearing that up.","commit_id":"bf52fdf43f45afffb4c180c8a4c6621b99151c98"}],"keystone/credential/core.py":[{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"23912d33181e9015c1f433582054e7a8b2e260af","unresolved":false,"context_lines":[{"line_number":77,"context_line":"        raise exception.NotImplemented()  # pragma: no cover"},{"line_number":78,"context_line":""},{"line_number":79,"context_line":"    @abc.abstractmethod"},{"line_number":80,"context_line":"    def list_credentials_for_user(self, user_id, type):"},{"line_number":81,"context_line":"        \"\"\"List credentials for a user."},{"line_number":82,"context_line":""},{"line_number":83,"context_line":"        :param user_id: ID of a user to filter credentials by."}],"source_content_type":"text/x-python","patch_set":5,"id":"ba8a016a_0c632143","line":80,"updated":"2015-11-20 02:57:34.000000000","message":"Perhaps adding the default value in the method signature would make it explicit that it is optional, as you actually do in the sql driver:\n\n    type\u003dNone","commit_id":"6d64d3dcbfda05963a148c28db23ac32e2f7cb50"},{"author":{"_account_id":10046,"name":"Henrique Truta","email":"henrique@lsd.ufcg.edu.br","username":"henriquetruta"},"change_message_id":"2c02e3c5e56b7d5106e86daedb3242997ac7b9b9","unresolved":false,"context_lines":[{"line_number":77,"context_line":"        raise exception.NotImplemented()  # pragma: no cover"},{"line_number":78,"context_line":""},{"line_number":79,"context_line":"    @abc.abstractmethod"},{"line_number":80,"context_line":"    def list_credentials_for_user(self, user_id, type):"},{"line_number":81,"context_line":"        \"\"\"List credentials for a user."},{"line_number":82,"context_line":""},{"line_number":83,"context_line":"        :param user_id: ID of a user to filter credentials by."}],"source_content_type":"text/x-python","patch_set":5,"id":"da85f559_91568a28","line":80,"updated":"2015-11-11 16:40:03.000000000","message":"maybe this could be made in another patch, to make the patches as granular as possible.","commit_id":"6d64d3dcbfda05963a148c28db23ac32e2f7cb50"},{"author":{"_account_id":14413,"name":"Tony Wang","username":"tony","inactive":true},"change_message_id":"c54da1beb7001a1215c85d8516eb5aca0fe63706","unresolved":false,"context_lines":[{"line_number":77,"context_line":"        raise exception.NotImplemented()  # pragma: no cover"},{"line_number":78,"context_line":""},{"line_number":79,"context_line":"    @abc.abstractmethod"},{"line_number":80,"context_line":"    def list_credentials_for_user(self, user_id, type):"},{"line_number":81,"context_line":"        \"\"\"List credentials for a user."},{"line_number":82,"context_line":""},{"line_number":83,"context_line":"        :param user_id: ID of a user to filter credentials by."}],"source_content_type":"text/x-python","patch_set":5,"id":"da85f559_fbf0faca","line":80,"in_reply_to":"da85f559_91568a28","updated":"2015-11-12 01:57:04.000000000","message":"Sorry, I don\u0027t quite understand.\nAs `Credential\u0027 class in sql.py is a subclass of this class, I think the function signatures should be consistent, if I understand correctly.","commit_id":"6d64d3dcbfda05963a148c28db23ac32e2f7cb50"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"3141c5debe7f8776d318da3a6004bac2765da32c","unresolved":false,"context_lines":[{"line_number":81,"context_line":"        \"\"\"List credentials for a user."},{"line_number":82,"context_line":""},{"line_number":83,"context_line":"        :param user_id: ID of a user to filter credentials by."},{"line_number":84,"context_line":"        :param type: type of expected credentials."},{"line_number":85,"context_line":""},{"line_number":86,"context_line":"        :returns: a list of credential_refs or an empty list."},{"line_number":87,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"9a8ffd7b_ed5ca54c","line":84,"updated":"2015-11-29 17:27:07.000000000","message":"this isn\u0027t accurate, maybe:\n\ntype of credentials to filter on","commit_id":"e9336929835a21cf5b6f83c2fac78b4356ad478b"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"c850819f674476247e310475f5b7004908121c25","unresolved":false,"context_lines":[{"line_number":77,"context_line":"        raise exception.NotImplemented()  # pragma: no cover"},{"line_number":78,"context_line":""},{"line_number":79,"context_line":"    @abc.abstractmethod"},{"line_number":80,"context_line":"    def list_credentials_for_user(self, user_id, type\u003dNone):"},{"line_number":81,"context_line":"        \"\"\"List credentials for a user."},{"line_number":82,"context_line":""},{"line_number":83,"context_line":"        :param user_id: ID of a user to filter credentials by."}],"source_content_type":"text/x-python","patch_set":9,"id":"fa69d971_280860d9","line":80,"updated":"2016-01-06 22:23:37.000000000","message":"Since we are changing the driver interface do we need to version bump. I realize it\u0027s backward compatible.","commit_id":"9fc1cc67d993cfa0afc46aaea2802e1c35445f77"}],"keystone/tests/unit/test_backend_sql.py":[{"author":{"_account_id":17123,"name":"Tom Cocozzello (tjcocozz)","email":"tjcocozz@us.ibm.com","username":"tcocozzello"},"change_message_id":"a4c8a4715f9781a106e0e0d6aaae9a4353bd74e8","unresolved":false,"context_lines":[{"line_number":924,"context_line":"        # list credentials of a specific type"},{"line_number":925,"context_line":"        cred \u003d self.user_credentials[0]"},{"line_number":926,"context_line":"        credentials \u003d self.credential_api.list_credentials_for_user("},{"line_number":927,"context_line":"            self.user_foo[\u0027id\u0027], type\u003dcred[\u0027type\u0027])"},{"line_number":928,"context_line":"        self.assertEqual(1, len(credentials))"},{"line_number":929,"context_line":"        self.assertEqual(cred[\u0027id\u0027], credentials[0][\u0027id\u0027])"}],"source_content_type":"text/x-python","patch_set":3,"id":"3a29b11f_adb0a7f5","line":927,"updated":"2015-10-19 15:48:28.000000000","message":"Why not use _validateCredentialList here instead of the two assertEqual\u0027s bellow?","commit_id":"bf52fdf43f45afffb4c180c8a4c6621b99151c98"},{"author":{"_account_id":14413,"name":"Tony Wang","username":"tony","inactive":true},"change_message_id":"7907097b462ef175ce57cca339aa951c0fdc2db2","unresolved":false,"context_lines":[{"line_number":924,"context_line":"        # list credentials of a specific type"},{"line_number":925,"context_line":"        cred \u003d self.user_credentials[0]"},{"line_number":926,"context_line":"        credentials \u003d self.credential_api.list_credentials_for_user("},{"line_number":927,"context_line":"            self.user_foo[\u0027id\u0027], type\u003dcred[\u0027type\u0027])"},{"line_number":928,"context_line":"        self.assertEqual(1, len(credentials))"},{"line_number":929,"context_line":"        self.assertEqual(cred[\u0027id\u0027], credentials[0][\u0027id\u0027])"}],"source_content_type":"text/x-python","patch_set":3,"id":"3a29b11f_bfba05e0","line":927,"in_reply_to":"3a29b11f_24182c1d","updated":"2015-10-19 16:21:43.000000000","message":"I see your point. I\u0027ll fix this.","commit_id":"bf52fdf43f45afffb4c180c8a4c6621b99151c98"},{"author":{"_account_id":17123,"name":"Tom Cocozzello (tjcocozz)","email":"tjcocozz@us.ibm.com","username":"tcocozzello"},"change_message_id":"9154746c6e35cf2daf376ce7c93977c1a4c37947","unresolved":false,"context_lines":[{"line_number":924,"context_line":"        # list credentials of a specific type"},{"line_number":925,"context_line":"        cred \u003d self.user_credentials[0]"},{"line_number":926,"context_line":"        credentials \u003d self.credential_api.list_credentials_for_user("},{"line_number":927,"context_line":"            self.user_foo[\u0027id\u0027], type\u003dcred[\u0027type\u0027])"},{"line_number":928,"context_line":"        self.assertEqual(1, len(credentials))"},{"line_number":929,"context_line":"        self.assertEqual(cred[\u0027id\u0027], credentials[0][\u0027id\u0027])"}],"source_content_type":"text/x-python","patch_set":3,"id":"3a29b11f_24182c1d","line":927,"in_reply_to":"3a29b11f_a40e7c32","updated":"2015-10-19 16:09:29.000000000","message":"yes that is right but the one that is returned is in a list, if you look at _validateCredentialList it does the same thing.  Its up to you which you choose I just wanted to let you know that is available.","commit_id":"bf52fdf43f45afffb4c180c8a4c6621b99151c98"},{"author":{"_account_id":14413,"name":"Tony Wang","username":"tony","inactive":true},"change_message_id":"7bfe796c1081da5aced6dd94b70e3af420b1277c","unresolved":false,"context_lines":[{"line_number":924,"context_line":"        # list credentials of a specific type"},{"line_number":925,"context_line":"        cred \u003d self.user_credentials[0]"},{"line_number":926,"context_line":"        credentials \u003d self.credential_api.list_credentials_for_user("},{"line_number":927,"context_line":"            self.user_foo[\u0027id\u0027], type\u003dcred[\u0027type\u0027])"},{"line_number":928,"context_line":"        self.assertEqual(1, len(credentials))"},{"line_number":929,"context_line":"        self.assertEqual(cred[\u0027id\u0027], credentials[0][\u0027id\u0027])"}],"source_content_type":"text/x-python","patch_set":3,"id":"3a29b11f_a40e7c32","line":927,"in_reply_to":"3a29b11f_adb0a7f5","updated":"2015-10-19 16:00:32.000000000","message":"The point is, with `type\u0027, only credentials whose type is the specified one will be returned, in this case, it\u0027s _one_ credential.\nSo the below two lines are to check that.","commit_id":"bf52fdf43f45afffb4c180c8a4c6621b99151c98"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"23912d33181e9015c1f433582054e7a8b2e260af","unresolved":false,"context_lines":[{"line_number":919,"context_line":"        cred \u003d self.user_credentials[0]"},{"line_number":920,"context_line":"        credentials \u003d self.credential_api.list_credentials_for_user("},{"line_number":921,"context_line":"            self.user_foo[\u0027id\u0027], type\u003dcred[\u0027type\u0027])"},{"line_number":922,"context_line":"        self._validateCredentialList(credentials, [cred])"}],"source_content_type":"text/x-python","patch_set":5,"id":"ba8a016a_ece81db5","line":922,"updated":"2015-11-20 02:57:34.000000000","message":"We need to assert all the returned credentials have the expected type.","commit_id":"6d64d3dcbfda05963a148c28db23ac32e2f7cb50"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"81b265cffab6312df5541b089bb50be74552b1fd","unresolved":false,"context_lines":[{"line_number":919,"context_line":"        cred \u003d self.user_credentials[0]"},{"line_number":920,"context_line":"        credentials \u003d self.credential_api.list_credentials_for_user("},{"line_number":921,"context_line":"            self.user_foo[\u0027id\u0027], type\u003dcred[\u0027type\u0027])"},{"line_number":922,"context_line":"        self._validateCredentialList(credentials, [cred])"}],"source_content_type":"text/x-python","patch_set":5,"id":"ba8a016a_71d700ee","line":922,"in_reply_to":"ba8a016a_3c6b9687","updated":"2015-11-20 16:38:04.000000000","message":"Ah, that\u0027s true, you already check that \u0027cred\u0027 is in the returned list.","commit_id":"6d64d3dcbfda05963a148c28db23ac32e2f7cb50"},{"author":{"_account_id":14413,"name":"Tony Wang","username":"tony","inactive":true},"change_message_id":"290606617e17b7bc6f18c65abd3aa5719588f4a5","unresolved":false,"context_lines":[{"line_number":919,"context_line":"        cred \u003d self.user_credentials[0]"},{"line_number":920,"context_line":"        credentials \u003d self.credential_api.list_credentials_for_user("},{"line_number":921,"context_line":"            self.user_foo[\u0027id\u0027], type\u003dcred[\u0027type\u0027])"},{"line_number":922,"context_line":"        self._validateCredentialList(credentials, [cred])"}],"source_content_type":"text/x-python","patch_set":5,"id":"ba8a016a_3c6b9687","line":922,"in_reply_to":"ba8a016a_ece81db5","updated":"2015-11-20 15:06:14.000000000","message":"The returned credential is just `cred\u0027. Requesting by cred\u0027s type, and server returning cred, is enough for presenting it works.\n\nI think it\u0027s kind of redundant to check cred\u0027s type equals to cred\u0027s type","commit_id":"6d64d3dcbfda05963a148c28db23ac32e2f7cb50"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"3141c5debe7f8776d318da3a6004bac2765da32c","unresolved":false,"context_lines":[{"line_number":800,"context_line":"            self.user_foo[\u0027id\u0027])"},{"line_number":801,"context_line":"        self._validateCredentialList(credentials, self.user_credentials)"},{"line_number":802,"context_line":""},{"line_number":803,"context_line":"        # list credentials of a specific type"},{"line_number":804,"context_line":"        cred \u003d self.user_credentials[0]"},{"line_number":805,"context_line":"        credentials \u003d self.credential_api.list_credentials_for_user("},{"line_number":806,"context_line":"            self.user_foo[\u0027id\u0027], type\u003dcred[\u0027type\u0027])"}],"source_content_type":"text/x-python","patch_set":7,"id":"9a8ffd7b_6d3755ff","line":803,"updated":"2015-11-29 17:27:07.000000000","message":"this should be it\u0027s own test:\n\n  def test_list_credentials_for_user_and_type\n\nand another:\n\n  def test_list_credentials_for_type","commit_id":"e9336929835a21cf5b6f83c2fac78b4356ad478b"},{"author":{"_account_id":13063,"name":"WEI CHEN","email":"dave.jungler@gmail.com","username":"wei.d.chen"},"change_message_id":"a9931ef43b0d3792ea5256c01f4fcc52ecbe4b12","unresolved":false,"context_lines":[{"line_number":800,"context_line":"            self.user_foo[\u0027id\u0027])"},{"line_number":801,"context_line":"        self._validateCredentialList(credentials, self.user_credentials)"},{"line_number":802,"context_line":""},{"line_number":803,"context_line":"        # list credentials of a specific type"},{"line_number":804,"context_line":"        cred \u003d self.user_credentials[0]"},{"line_number":805,"context_line":"        credentials \u003d self.credential_api.list_credentials_for_user("},{"line_number":806,"context_line":"            self.user_foo[\u0027id\u0027], type\u003dcred[\u0027type\u0027])"}],"source_content_type":"text/x-python","patch_set":7,"id":"9a8ffd7b_3c8e5c2e","line":803,"in_reply_to":"9a8ffd7b_6d3755ff","updated":"2015-11-29 20:26:20.000000000","message":"++ Good call!","commit_id":"e9336929835a21cf5b6f83c2fac78b4356ad478b"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"9d3c2f4a51a2569d57b40ec92bab84b371ddc858","unresolved":false,"context_lines":[{"line_number":804,"context_line":"        cred \u003d self.user_credentials[0]"},{"line_number":805,"context_line":"        credentials \u003d self.credential_api.list_credentials_for_user("},{"line_number":806,"context_line":"            self.user_foo[\u0027id\u0027], type\u003dcred[\u0027type\u0027])"},{"line_number":807,"context_line":"        self._validateCredentialList(credentials, [cred])"}],"source_content_type":"text/x-python","patch_set":8,"id":"7a740942_af4abf81","line":807,"updated":"2015-12-04 12:22:52.000000000","message":"You should add a test for filtering only by type, as suggested by Steve in the previous patchset","commit_id":"e41dd4f645687747f50d352f6f27561b81763af1"},{"author":{"_account_id":14413,"name":"Tony Wang","username":"tony","inactive":true},"change_message_id":"f1980ad42868a468e826924422a4326383c70110","unresolved":false,"context_lines":[{"line_number":804,"context_line":"        cred \u003d self.user_credentials[0]"},{"line_number":805,"context_line":"        credentials \u003d self.credential_api.list_credentials_for_user("},{"line_number":806,"context_line":"            self.user_foo[\u0027id\u0027], type\u003dcred[\u0027type\u0027])"},{"line_number":807,"context_line":"        self._validateCredentialList(credentials, [cred])"}],"source_content_type":"text/x-python","patch_set":8,"id":"7a740942_60e8617d","line":807,"in_reply_to":"7a740942_af4abf81","updated":"2015-12-04 13:50:54.000000000","message":"I forgot to reply his comment, that user_id is a necessary argument for method `list_credentials_for_user`","commit_id":"e41dd4f645687747f50d352f6f27561b81763af1"}],"keystone/tests/unit/test_credential.py":[{"author":{"_account_id":13063,"name":"WEI CHEN","email":"dave.jungler@gmail.com","username":"wei.d.chen"},"change_message_id":"a9931ef43b0d3792ea5256c01f4fcc52ecbe4b12","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# Copyright 2015 OpenStack Foundation"},{"line_number":2,"context_line":"#"},{"line_number":3,"context_line":"# Licensed under the Apache License, Version 2.0 (the \"License\"); you may"},{"line_number":4,"context_line":"# not use this file except in compliance with the License. You may obtain"}],"source_content_type":"text/x-python","patch_set":7,"id":"9a8ffd7b_dc8070f9","line":1,"updated":"2015-11-29 20:26:20.000000000","message":"change your affiliation.","commit_id":"e9336929835a21cf5b6f83c2fac78b4356ad478b"},{"author":{"_account_id":13063,"name":"WEI CHEN","email":"dave.jungler@gmail.com","username":"wei.d.chen"},"change_message_id":"a9931ef43b0d3792ea5256c01f4fcc52ecbe4b12","unresolved":false,"context_lines":[{"line_number":10,"context_line":"# distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT"},{"line_number":11,"context_line":"# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the"},{"line_number":12,"context_line":"# License for the specific language governing permissions and limitations"},{"line_number":13,"context_line":"# under the License."},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"import uuid"},{"line_number":16,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"9a8ffd7b_dc971038","line":13,"updated":"2015-11-29 20:26:20.000000000","message":"These is already a test module to test ec2 specific behavior, I am not insist on to move these into that one, but it\u0027s a good chance to expand the old one. Let\u0027s see is there any other inputs for this.\n\nsee: https://github.com/openstack/keystone/blob/master/keystone/tests/unit/test_contrib_ec2.py#L27-L29","commit_id":"e9336929835a21cf5b6f83c2fac78b4356ad478b"},{"author":{"_account_id":14413,"name":"Tony Wang","username":"tony","inactive":true},"change_message_id":"663d3cb6463b294b3b4d9da691d44785af08e807","unresolved":false,"context_lines":[{"line_number":10,"context_line":"# distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT"},{"line_number":11,"context_line":"# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the"},{"line_number":12,"context_line":"# License for the specific language governing permissions and limitations"},{"line_number":13,"context_line":"# under the License."},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"import uuid"},{"line_number":16,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"9a8ffd7b_3f9bae19","line":13,"in_reply_to":"9a8ffd7b_dc971038","updated":"2015-11-30 01:11:31.000000000","message":"Please check my comment about patch set 7.\n\nI saw your comment in last patch set about that, and I tried. But test_contrib_ec2.py is in Python 3 test list, and there seems to be some unicode related issue to call APIs.","commit_id":"e9336929835a21cf5b6f83c2fac78b4356ad478b"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"3141c5debe7f8776d318da3a6004bac2765da32c","unresolved":false,"context_lines":[{"line_number":58,"context_line":"                            path\u003dpath,"},{"line_number":59,"context_line":"                            expected_status\u003dhttp_client.UNAUTHORIZED)"},{"line_number":60,"context_line":""},{"line_number":61,"context_line":"    def assertValidErrorResponse(self, r):"},{"line_number":62,"context_line":"        # FIXME(wwwjfy): it\u0027s copied from test_v3.py. The logic of this method"},{"line_number":63,"context_line":"        # in test_v2.py and test_v3.py (both are inherited from rest.py) has no"},{"line_number":64,"context_line":"        # difference, so they should be refactored into one place. Also, the"}],"source_content_type":"text/x-python","patch_set":7,"id":"9a8ffd7b_48a4bfb8","line":61,"updated":"2015-11-29 17:27:07.000000000","message":"where is this used?","commit_id":"e9336929835a21cf5b6f83c2fac78b4356ad478b"},{"author":{"_account_id":13063,"name":"WEI CHEN","email":"dave.jungler@gmail.com","username":"wei.d.chen"},"change_message_id":"a9931ef43b0d3792ea5256c01f4fcc52ecbe4b12","unresolved":false,"context_lines":[{"line_number":58,"context_line":"                            path\u003dpath,"},{"line_number":59,"context_line":"                            expected_status\u003dhttp_client.UNAUTHORIZED)"},{"line_number":60,"context_line":""},{"line_number":61,"context_line":"    def assertValidErrorResponse(self, r):"},{"line_number":62,"context_line":"        # FIXME(wwwjfy): it\u0027s copied from test_v3.py. The logic of this method"},{"line_number":63,"context_line":"        # in test_v2.py and test_v3.py (both are inherited from rest.py) has no"},{"line_number":64,"context_line":"        # difference, so they should be refactored into one place. Also, the"}],"source_content_type":"text/x-python","patch_set":7,"id":"9a8ffd7b_bca1ec95","line":61,"in_reply_to":"9a8ffd7b_48a4bfb8","updated":"2015-11-29 20:26:20.000000000","message":"++\n\nIf import this let\u0027s reference with this method.","commit_id":"e9336929835a21cf5b6f83c2fac78b4356ad478b"},{"author":{"_account_id":14413,"name":"Tony Wang","username":"tony","inactive":true},"change_message_id":"663d3cb6463b294b3b4d9da691d44785af08e807","unresolved":false,"context_lines":[{"line_number":58,"context_line":"                            path\u003dpath,"},{"line_number":59,"context_line":"                            expected_status\u003dhttp_client.UNAUTHORIZED)"},{"line_number":60,"context_line":""},{"line_number":61,"context_line":"    def assertValidErrorResponse(self, r):"},{"line_number":62,"context_line":"        # FIXME(wwwjfy): it\u0027s copied from test_v3.py. The logic of this method"},{"line_number":63,"context_line":"        # in test_v2.py and test_v3.py (both are inherited from rest.py) has no"},{"line_number":64,"context_line":"        # difference, so they should be refactored into one place. Also, the"}],"source_content_type":"text/x-python","patch_set":7,"id":"9a8ffd7b_5f579225","line":61,"in_reply_to":"9a8ffd7b_48a4bfb8","updated":"2015-11-30 01:11:31.000000000","message":"I tried to make it clear in the FIXME.\n\nunit/test_v2.py and unit/test_v3.py inherit rest.RestfulTestCase and change the function signature (and how it works) of assertValidErrorResponse, but in method restful_request in unit/rest.py, it\u0027s called by the new way.\n\nIn short, assertValidErrorResponse in unit/rest.py checks if the status code equals to 400, and there is no way to change that from argument.\n\nSo I added a temp hack here, and I\u0027ll commit another patch to fix it after this merged.","commit_id":"e9336929835a21cf5b6f83c2fac78b4356ad478b"},{"author":{"_account_id":14413,"name":"Tony Wang","username":"tony","inactive":true},"change_message_id":"663d3cb6463b294b3b4d9da691d44785af08e807","unresolved":false,"context_lines":[{"line_number":58,"context_line":"                            path\u003dpath,"},{"line_number":59,"context_line":"                            expected_status\u003dhttp_client.UNAUTHORIZED)"},{"line_number":60,"context_line":""},{"line_number":61,"context_line":"    def assertValidErrorResponse(self, r):"},{"line_number":62,"context_line":"        # FIXME(wwwjfy): it\u0027s copied from test_v3.py. The logic of this method"},{"line_number":63,"context_line":"        # in test_v2.py and test_v3.py (both are inherited from rest.py) has no"},{"line_number":64,"context_line":"        # difference, so they should be refactored into one place. Also, the"}],"source_content_type":"text/x-python","patch_set":7,"id":"9a8ffd7b_1f4d8a99","line":61,"in_reply_to":"9a8ffd7b_bca1ec95","updated":"2015-11-30 01:11:31.000000000","message":"It\u0027s inherited from rest.RestfulTestCase","commit_id":"e9336929835a21cf5b6f83c2fac78b4356ad478b"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"35511ee9cc553a53c8f4e8bb7418c46b476d0b7c","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":9,"id":"5a710552_2e2ca849","updated":"2015-12-15 06:18:32.000000000","message":"this can be merged with https://github.com/openstack/keystone/blob/44d0c2f5a5c678fa866a3220db38b8881a7cb9ed/keystone/tests/unit/test_contrib_ec2.py i think\n\ni\u0027ll post a follow on patch","commit_id":"9fc1cc67d993cfa0afc46aaea2802e1c35445f77"},{"author":{"_account_id":14413,"name":"Tony Wang","username":"tony","inactive":true},"change_message_id":"a4d8c7ec77c8664e0d057c4b68107c2118a2c147","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":9,"id":"5a710552_ceff2433","in_reply_to":"5a710552_2e2ca849","updated":"2015-12-15 06:28:40.000000000","message":"Actually I was adding tests there. The problem I met is that there seems to be some Python 3 related issues with public_request, so I created a new file","commit_id":"9fc1cc67d993cfa0afc46aaea2802e1c35445f77"},{"author":{"_account_id":13063,"name":"WEI CHEN","email":"dave.jungler@gmail.com","username":"wei.d.chen"},"change_message_id":"692124819211a7cbaeb6e5ecee37802f9c9a246d","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":9,"id":"5a710552_e63769ae","in_reply_to":"5a710552_ceff2433","updated":"2015-12-16 04:47:13.000000000","message":"if this fails for python3, then this is another issue we should fix, we are going to support both python2 and python3 for unittest, anyway, i am fine with as is.","commit_id":"9fc1cc67d993cfa0afc46aaea2802e1c35445f77"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"c850819f674476247e310475f5b7004908121c25","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":9,"id":"fa69d971_88eb8cdb","in_reply_to":"5a710552_e63769ae","updated":"2016-01-06 22:23:37.000000000","message":"If we do leave this here then we need a TODO comment saying that it should be merged with the file Steve mentioned.","commit_id":"9fc1cc67d993cfa0afc46aaea2802e1c35445f77"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"3b889dd61fba03b1c89a2391628769b0846c4e61","unresolved":false,"context_lines":[{"line_number":90,"context_line":"                                path\u003duri)"},{"line_number":91,"context_line":"        cred_list_2 \u003d r.result[\u0027credentials\u0027]"},{"line_number":92,"context_line":"        # still one element because non-EC2 credentials are not returned."},{"line_number":93,"context_line":"        self.assertEqual(1, len(cred_list_2))"},{"line_number":94,"context_line":"        self.assertEqual(cred_list[0], cred_list_2[0])"}],"source_content_type":"text/x-python","patch_set":9,"id":"fa69d971_320e948c","line":93,"updated":"2016-01-06 20:33:28.000000000","message":"nit: could add another ec2 type credential and ensure we get two entries back.","commit_id":"9fc1cc67d993cfa0afc46aaea2802e1c35445f77"}],"keystone/tests/unit/test_v3_credential.py":[{"author":{"_account_id":18835,"name":"Toshiya Shiga","email":"tos-shiga@yk.jp.nec.com","username":"tos-shiga"},"change_message_id":"4c6aa8092a62b6a1b78fcca22ee115680186e037","unresolved":false,"context_lines":[{"line_number":469,"context_line":"        self.assertThat(r.result[\u0027links\u0027][\u0027self\u0027],"},{"line_number":470,"context_line":"                        matchers.EndsWith(uri))"},{"line_number":471,"context_line":""},{"line_number":472,"context_line":"        # non ec2 credentials won\u0027t be fetched"},{"line_number":473,"context_line":"        non_ec2_cred \u003d self.new_credential_ref("},{"line_number":474,"context_line":"            user_id\u003dself.user_id,"},{"line_number":475,"context_line":"            project_id\u003dself.project_id)"}],"source_content_type":"text/x-python","patch_set":5,"id":"ba8a016a_25daa418","line":472,"updated":"2015-11-20 13:11:45.000000000","message":"Why don\u0027t you unify word about \"non ec2\" and \"non-EC2\"(L481)?","commit_id":"6d64d3dcbfda05963a148c28db23ac32e2f7cb50"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"23912d33181e9015c1f433582054e7a8b2e260af","unresolved":false,"context_lines":[{"line_number":479,"context_line":"        r \u003d self.get(uri)"},{"line_number":480,"context_line":"        cred_list \u003d r.result[\u0027credentials\u0027]"},{"line_number":481,"context_line":"        # still one element because non-EC2 credentials are not returned."},{"line_number":482,"context_line":"        self.assertEqual(1, len(cred_list))"},{"line_number":483,"context_line":""},{"line_number":484,"context_line":"    def test_ec2_delete_credential(self):"},{"line_number":485,"context_line":"        \"\"\"Test ec2 credential deletion.\"\"\""}],"source_content_type":"text/x-python","patch_set":5,"id":"ba8a016a_2c1865d2","line":482,"updated":"2015-11-20 02:57:34.000000000","message":"Perhaps checking the cred_list is the same as the old one from L467 would be a good idea.","commit_id":"6d64d3dcbfda05963a148c28db23ac32e2f7cb50"},{"author":{"_account_id":13063,"name":"WEI CHEN","email":"dave.jungler@gmail.com","username":"wei.d.chen"},"change_message_id":"a9931ef43b0d3792ea5256c01f4fcc52ecbe4b12","unresolved":false,"context_lines":[{"line_number":16,"context_line":"import json"},{"line_number":17,"context_line":"import uuid"},{"line_number":18,"context_line":""},{"line_number":19,"context_line":"from keystone.contrib.ec2 import controllers"},{"line_number":20,"context_line":"from keystoneclient.contrib.ec2 import utils as ec2_utils"},{"line_number":21,"context_line":"from oslo_config import cfg"},{"line_number":22,"context_line":"from six.moves import http_client"}],"source_content_type":"text/x-python","patch_set":7,"id":"9a8ffd7b_dcae3080","line":19,"updated":"2015-11-29 20:26:20.000000000","message":"move this line to the next section. It\u0027s not belonged here.","commit_id":"e9336929835a21cf5b6f83c2fac78b4356ad478b"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"3141c5debe7f8776d318da3a6004bac2765da32c","unresolved":false,"context_lines":[{"line_number":29,"context_line":""},{"line_number":30,"context_line":""},{"line_number":31,"context_line":"CONF \u003d cfg.CONF"},{"line_number":32,"context_line":"CRED_TYPE_EC2 \u003d controllers.CRED_TYPE_EC2"},{"line_number":33,"context_line":""},{"line_number":34,"context_line":""},{"line_number":35,"context_line":"class CredentialBaseTestCase(test_v3.RestfulTestCase):"}],"source_content_type":"text/x-python","patch_set":7,"id":"9a8ffd7b_68a743bd","line":32,"updated":"2015-11-29 17:27:07.000000000","message":"nice re-use","commit_id":"e9336929835a21cf5b6f83c2fac78b4356ad478b"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"35511ee9cc553a53c8f4e8bb7418c46b476d0b7c","unresolved":false,"context_lines":[{"line_number":443,"context_line":"        self.assertThat(r.result[\u0027links\u0027][\u0027self\u0027],"},{"line_number":444,"context_line":"                        matchers.EndsWith(uri))"},{"line_number":445,"context_line":""},{"line_number":446,"context_line":"        # non-EC2 credentials won\u0027t be fetched"},{"line_number":447,"context_line":"        non_ec2_cred \u003d unit.new_credential_ref("},{"line_number":448,"context_line":"            user_id\u003dself.user_id,"},{"line_number":449,"context_line":"            project_id\u003dself.project_id)"}],"source_content_type":"text/x-python","patch_set":9,"id":"5a710552_6ee71041","line":446,"updated":"2015-12-15 06:18:32.000000000","message":"this should be it\u0027s own test","commit_id":"9fc1cc67d993cfa0afc46aaea2802e1c35445f77"},{"author":{"_account_id":13063,"name":"WEI CHEN","email":"dave.jungler@gmail.com","username":"wei.d.chen"},"change_message_id":"692124819211a7cbaeb6e5ecee37802f9c9a246d","unresolved":false,"context_lines":[{"line_number":443,"context_line":"        self.assertThat(r.result[\u0027links\u0027][\u0027self\u0027],"},{"line_number":444,"context_line":"                        matchers.EndsWith(uri))"},{"line_number":445,"context_line":""},{"line_number":446,"context_line":"        # non-EC2 credentials won\u0027t be fetched"},{"line_number":447,"context_line":"        non_ec2_cred \u003d unit.new_credential_ref("},{"line_number":448,"context_line":"            user_id\u003dself.user_id,"},{"line_number":449,"context_line":"            project_id\u003dself.project_id)"}],"source_content_type":"text/x-python","patch_set":9,"id":"5a710552_26e81110","line":446,"in_reply_to":"5a710552_6ee71041","updated":"2015-12-16 04:47:13.000000000","message":"++","commit_id":"9fc1cc67d993cfa0afc46aaea2802e1c35445f77"}]}
