)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"7fb6beb30788a51636ee4f144788ae02ec2576cd","unresolved":false,"context_lines":[{"line_number":7,"context_line":"Add CADF notifications for role assignment create and delete"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Assigning and removing roles from users|groups and projects|domains"},{"line_number":10,"context_line":"should be an auditable events. Thus, we should start sending out"},{"line_number":11,"context_line":"notifications when these events occur."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"implements bp role-assignment-notifications"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":24,"id":"1abeadc6_85aaa56e","line":10,"updated":"2014-08-18 20:04:10.000000000","message":"change \"events\" to \"event\"","commit_id":"75fd871b0e056b72be457c1e8f5bbf3838439258"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"6c158a55d196741d5ed8ce45bca2997a3321a228","unresolved":false,"context_lines":[{"line_number":7,"context_line":"Add CADF notifications for role assignment create and delete"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Assigning and removing roles from users|groups and projects|domains"},{"line_number":10,"context_line":"should be an auditable events. Thus, we should start sending out"},{"line_number":11,"context_line":"notifications when these events occur."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"implements bp role-assignment-notifications"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":24,"id":"1abeadc6_a9da1b76","line":10,"in_reply_to":"1abeadc6_85aaa56e","updated":"2014-08-18 20:10:51.000000000","message":"Done","commit_id":"75fd871b0e056b72be457c1e8f5bbf3838439258"}],"keystone/assignment/core.py":[{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"8c54d5a5c11c5112915c31bb2b329de772b6976b","unresolved":false,"context_lines":[{"line_number":60,"context_line":"    api object by both managers."},{"line_number":61,"context_line":"    \"\"\""},{"line_number":62,"context_line":"    _PROJECT \u003d \u0027project\u0027"},{"line_number":63,"context_line":"    _GRANT \u003d \u0027grant\u0027"},{"line_number":64,"context_line":""},{"line_number":65,"context_line":"    def __init__(self):"},{"line_number":66,"context_line":"        assignment_driver \u003d CONF.assignment.driver"}],"source_content_type":"text/x-python","patch_set":1,"id":"baada198_9b6f68c7","line":63,"updated":"2014-08-06 06:15:52.000000000","message":"i could call this a role_assignment if it helps folks sleep better at night.","commit_id":"37cb8248b7fa755c52047598efe0d271504eb965"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"2fba176d7a9ee6e524fc7c86424d114be58a3a7b","unresolved":false,"context_lines":[{"line_number":60,"context_line":"    api object by both managers."},{"line_number":61,"context_line":"    \"\"\""},{"line_number":62,"context_line":"    _PROJECT \u003d \u0027project\u0027"},{"line_number":63,"context_line":"    _GRANT \u003d \u0027grant\u0027"},{"line_number":64,"context_line":""},{"line_number":65,"context_line":"    def __init__(self):"},{"line_number":66,"context_line":"        assignment_driver \u003d CONF.assignment.driver"}],"source_content_type":"text/x-python","patch_set":1,"id":"baada198_f5e4e443","line":63,"in_reply_to":"baada198_9b6f68c7","updated":"2014-08-06 12:47:08.000000000","message":"I think that would be good....we\u0027ve been trying to kill the G word for about 3 releases...:-)","commit_id":"37cb8248b7fa755c52047598efe0d271504eb965"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"d8cd460909dfe74eaadf374825f0c0c0c181bd84","unresolved":false,"context_lines":[{"line_number":60,"context_line":"    api object by both managers."},{"line_number":61,"context_line":"    \"\"\""},{"line_number":62,"context_line":"    _PROJECT \u003d \u0027project\u0027"},{"line_number":63,"context_line":"    _GRANT \u003d \u0027grant\u0027"},{"line_number":64,"context_line":""},{"line_number":65,"context_line":"    def __init__(self):"},{"line_number":66,"context_line":"        assignment_driver \u003d CONF.assignment.driver"}],"source_content_type":"text/x-python","patch_set":1,"id":"baada198_55a03042","line":63,"in_reply_to":"baada198_f5e4e443","updated":"2014-08-06 12:57:07.000000000","message":"done","commit_id":"37cb8248b7fa755c52047598efe0d271504eb965"},{"author":{"_account_id":9101,"name":"wanghong","email":"reviewwanghong@126.com","username":"wanghong"},"change_message_id":"b46f2b34e7398250194e49b20154f164b0e333a3","unresolved":false,"context_lines":[{"line_number":60,"context_line":"    api object by both managers."},{"line_number":61,"context_line":"    \"\"\""},{"line_number":62,"context_line":"    _PROJECT \u003d \u0027project\u0027"},{"line_number":63,"context_line":"    _ROLE_ASSIGNMENT \u003d \u0027role_assignment\u0027"},{"line_number":64,"context_line":""},{"line_number":65,"context_line":"    def __init__(self):"},{"line_number":66,"context_line":"        assignment_driver \u003d CONF.assignment.driver"}],"source_content_type":"text/x-python","patch_set":3,"id":"baada198_9559a52b","line":63,"updated":"2014-08-08 03:34:49.000000000","message":"Unused variable.","commit_id":"10112290062a565e35ec9836e81ecaace589bbb8"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"2ebc0f57531c2b68c85a176016b1b871fb5977e9","unresolved":false,"context_lines":[{"line_number":60,"context_line":"    api object by both managers."},{"line_number":61,"context_line":"    \"\"\""},{"line_number":62,"context_line":"    _PROJECT \u003d \u0027project\u0027"},{"line_number":63,"context_line":"    _ROLE_ASSIGNMENT \u003d \u0027role_assignment\u0027"},{"line_number":64,"context_line":""},{"line_number":65,"context_line":"    def __init__(self):"},{"line_number":66,"context_line":"        assignment_driver \u003d CONF.assignment.driver"}],"source_content_type":"text/x-python","patch_set":3,"id":"baada198_75541122","line":63,"in_reply_to":"baada198_9559a52b","updated":"2014-08-08 04:21:32.000000000","message":"++ thanks","commit_id":"10112290062a565e35ec9836e81ecaace589bbb8"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"d5a1435e371cea4a5ec8b2e3ef329e8c471f3c7b","unresolved":false,"context_lines":[{"line_number":518,"context_line":"            self.revoke_api.revoke_by_grant(role_id, user_id\u003duser_id,"},{"line_number":519,"context_line":"                                            project_id\u003dtenant_id)"},{"line_number":520,"context_line":""},{"line_number":521,"context_line":"    @notifications.role_assignment(\u0027created\u0027)"},{"line_number":522,"context_line":"    def create_grant(self, role_id, user_id\u003dNone, group_id\u003dNone,"},{"line_number":523,"context_line":"                     domain_id\u003dNone, project_id\u003dNone,"},{"line_number":524,"context_line":"                     inherited_to_projects\u003dFalse, context\u003dNone):"}],"source_content_type":"text/x-python","patch_set":31,"id":"1abeadc6_e70aef24","line":521,"updated":"2014-08-21 21:55:17.000000000","message":"I like the way these read.","commit_id":"cc4f9e072d95b8ccc284d5e377fece299a3a0eb2"}],"keystone/notifications.py":[{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"e42584cf2555d2edbf23d4ead1f820f2e65aa9f7","unresolved":false,"context_lines":[{"line_number":77,"context_line":"                raise"},{"line_number":78,"context_line":"            else:"},{"line_number":79,"context_line":"                if self.resource_type \u003d\u003d \u0027role_assignment\u0027:"},{"line_number":80,"context_line":"                    resource_id \u003d kwargs[\u0027role_id\u0027]"},{"line_number":81,"context_line":"                elif self.result_id_arg_attr is not None:"},{"line_number":82,"context_line":"                    resource_id \u003d result[self.result_id_arg_attr]"},{"line_number":83,"context_line":"                else:"}],"source_content_type":"text/x-python","patch_set":2,"id":"baada198_ed325cbf","line":80,"updated":"2014-08-06 13:59:30.000000000","message":"is there a particular reason we don\u0027t just use the default resource_id_arg_index to pick up the role_id ?","commit_id":"481dc8a9bc2cec0dfde3c2aa01fa4bb87184ebec"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"d143eec8dcc515259eb59e243d6241812caa57cd","unresolved":false,"context_lines":[{"line_number":77,"context_line":"                raise"},{"line_number":78,"context_line":"            else:"},{"line_number":79,"context_line":"                if self.resource_type \u003d\u003d \u0027role_assignment\u0027:"},{"line_number":80,"context_line":"                    resource_id \u003d kwargs[\u0027role_id\u0027]"},{"line_number":81,"context_line":"                elif self.result_id_arg_attr is not None:"},{"line_number":82,"context_line":"                    resource_id \u003d result[self.result_id_arg_attr]"},{"line_number":83,"context_line":"                else:"}],"source_content_type":"text/x-python","patch_set":2,"id":"baada198_cd4678a7","line":80,"in_reply_to":"baada198_6dcc8c63","updated":"2014-08-06 16:49:21.000000000","message":"ah, I see the problem, although not quite sure that will fix it...","commit_id":"481dc8a9bc2cec0dfde3c2aa01fa4bb87184ebec"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"b6809f097b37d926cd00ba4b6bb7e16dfd85a3d6","unresolved":false,"context_lines":[{"line_number":77,"context_line":"                raise"},{"line_number":78,"context_line":"            else:"},{"line_number":79,"context_line":"                if self.resource_type \u003d\u003d \u0027role_assignment\u0027:"},{"line_number":80,"context_line":"                    resource_id \u003d kwargs[\u0027role_id\u0027]"},{"line_number":81,"context_line":"                elif self.result_id_arg_attr is not None:"},{"line_number":82,"context_line":"                    resource_id \u003d result[self.result_id_arg_attr]"},{"line_number":83,"context_line":"                else:"}],"source_content_type":"text/x-python","patch_set":2,"id":"baada198_8330c807","line":80,"in_reply_to":"baada198_cd4678a7","updated":"2014-08-06 18:03:52.000000000","message":"role_id is not passed in as kwargs to you won\u0027t find it there. Based on the method signatures you\u0027ll find the role_id at args[1].","commit_id":"481dc8a9bc2cec0dfde3c2aa01fa4bb87184ebec"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"e5aa8b2c96e6fa7b99ce377def0ba931088054bf","unresolved":false,"context_lines":[{"line_number":77,"context_line":"                raise"},{"line_number":78,"context_line":"            else:"},{"line_number":79,"context_line":"                if self.resource_type \u003d\u003d \u0027role_assignment\u0027:"},{"line_number":80,"context_line":"                    resource_id \u003d kwargs[\u0027role_id\u0027]"},{"line_number":81,"context_line":"                elif self.result_id_arg_attr is not None:"},{"line_number":82,"context_line":"                    resource_id \u003d result[self.result_id_arg_attr]"},{"line_number":83,"context_line":"                else:"}],"source_content_type":"text/x-python","patch_set":2,"id":"baada198_6dcc8c63","line":80,"in_reply_to":"baada198_ed325cbf","updated":"2014-08-06 14:07:02.000000000","message":"yeah, sadly it\u0027s because the tests call \n  assignment_api,create_grant(role_id\u003d\u0027xyz\u0027, user_id\u003d...)\nor\n  assignment_api,create_grant(user_id\u003d\u0027abc\u0027, role_id\u003d\u0027xyz\u0027, user_id\u003d...)\nor\n  assignment_api,create_grant(\u0027xyz\u0027, user_id\u003d...)\n\nbut `resource_id_arg_index` only works properly if it\u0027s a positional argument. \n\nSo in the case of the tests that were calling role_id\u003d\u0027something\u0027, resource_id_arg_index was defaulting to 1, and args[] just had the context, and kwargs had the keyword args.\n\nthe alternative would be to update all the tests, which was a lot of tests.","commit_id":"481dc8a9bc2cec0dfde3c2aa01fa4bb87184ebec"},{"author":{"_account_id":9101,"name":"wanghong","email":"reviewwanghong@126.com","username":"wanghong"},"change_message_id":"b46f2b34e7398250194e49b20154f164b0e333a3","unresolved":false,"context_lines":[{"line_number":138,"context_line":"                    if target is None:"},{"line_number":139,"context_line":"                        target \u003d args[3]"},{"line_number":140,"context_line":""},{"line_number":141,"context_line":"                payload.update({\u0027target\u0027: target, \u0027actor\u0027: actor})"},{"line_number":142,"context_line":"                _send_notification(self.operation, \u0027role_assignment\u0027, payload)"},{"line_number":143,"context_line":"            return result"},{"line_number":144,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"baada198_5542ad0d","line":141,"updated":"2014-08-08 03:34:49.000000000","message":"How about moving \u0027target\u0027 and \u0027actor\u0027 into resource_info? Like this:\n\n{\u0027resource_info\u0027: {\u0027resource_id\u0027: role_id, \u0027target\u0027: target, \u0027actor\u0027: actor}}","commit_id":"10112290062a565e35ec9836e81ecaace589bbb8"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"8b6e0bf70f733901120956d44b4d182589751d04","unresolved":false,"context_lines":[{"line_number":138,"context_line":"                    if target is None:"},{"line_number":139,"context_line":"                        target \u003d args[3]"},{"line_number":140,"context_line":""},{"line_number":141,"context_line":"                payload.update({\u0027target\u0027: target, \u0027actor\u0027: actor})"},{"line_number":142,"context_line":"                _send_notification(self.operation, \u0027role_assignment\u0027, payload)"},{"line_number":143,"context_line":"            return result"},{"line_number":144,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"baada198_b49855cd","line":141,"in_reply_to":"baada198_0be738e4","updated":"2014-08-08 15:33:21.000000000","message":"alright, good enough reason","commit_id":"10112290062a565e35ec9836e81ecaace589bbb8"},{"author":{"_account_id":9101,"name":"wanghong","email":"reviewwanghong@126.com","username":"wanghong"},"change_message_id":"c035c49641be5718e14a99064ae36076fca7ae8f","unresolved":false,"context_lines":[{"line_number":138,"context_line":"                    if target is None:"},{"line_number":139,"context_line":"                        target \u003d args[3]"},{"line_number":140,"context_line":""},{"line_number":141,"context_line":"                payload.update({\u0027target\u0027: target, \u0027actor\u0027: actor})"},{"line_number":142,"context_line":"                _send_notification(self.operation, \u0027role_assignment\u0027, payload)"},{"line_number":143,"context_line":"            return result"},{"line_number":144,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"baada198_0be738e4","line":141,"in_reply_to":"baada198_3521b9b5","updated":"2014-08-08 06:02:05.000000000","message":"I think that target and actor are all resource_info too:)","commit_id":"10112290062a565e35ec9836e81ecaace589bbb8"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"2ebc0f57531c2b68c85a176016b1b871fb5977e9","unresolved":false,"context_lines":[{"line_number":138,"context_line":"                    if target is None:"},{"line_number":139,"context_line":"                        target \u003d args[3]"},{"line_number":140,"context_line":""},{"line_number":141,"context_line":"                payload.update({\u0027target\u0027: target, \u0027actor\u0027: actor})"},{"line_number":142,"context_line":"                _send_notification(self.operation, \u0027role_assignment\u0027, payload)"},{"line_number":143,"context_line":"            return result"},{"line_number":144,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"baada198_3521b9b5","line":141,"in_reply_to":"baada198_5542ad0d","updated":"2014-08-08 04:21:32.000000000","message":"i don\u0027t really see the advantage, but if others think it\u0027s a good idea, i\u0027ll change it up","commit_id":"10112290062a565e35ec9836e81ecaace589bbb8"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"d7c4d77c92d01118874fd41b6940d737a3b30865","unresolved":false,"context_lines":[{"line_number":124,"context_line":"                elif \u0027group_id\u0027 in kwargs:"},{"line_number":125,"context_line":"                    actor \u003d kwargs.get(\u0027group_id\u0027)"},{"line_number":126,"context_line":""},{"line_number":127,"context_line":"                # try to get actor from args 0 or 1"},{"line_number":128,"context_line":"                if actor is None:"},{"line_number":129,"context_line":"                    actor \u003d args[0]"},{"line_number":130,"context_line":"                    if actor is None:"}],"source_content_type":"text/x-python","patch_set":4,"id":"baada198_74e156fb","line":127,"updated":"2014-08-08 18:20:22.000000000","message":"I think that we probably need some comments here as to why we need this convoluted way of getting the actor/target","commit_id":"8cd227d50f9f079a1e1c300a6419c7172e79f2e8"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"f0f1572ce0b6eee5e4baf21efba185802c1e16db","unresolved":false,"context_lines":[{"line_number":124,"context_line":"                elif \u0027group_id\u0027 in kwargs:"},{"line_number":125,"context_line":"                    actor \u003d kwargs.get(\u0027group_id\u0027)"},{"line_number":126,"context_line":""},{"line_number":127,"context_line":"                # try to get actor from args 0 or 1"},{"line_number":128,"context_line":"                if actor is None:"},{"line_number":129,"context_line":"                    actor \u003d args[0]"},{"line_number":130,"context_line":"                    if actor is None:"}],"source_content_type":"text/x-python","patch_set":4,"id":"baada198_f4df260a","line":127,"in_reply_to":"baada198_74e156fb","updated":"2014-08-08 18:24:08.000000000","message":"Sure, I\u0027ll comment / doc this, basically it\u0027s because create_grant can be called in a bunch of different ways, using positional or named arguments.\n\nSo target and actor might be in kwargs, or in args.","commit_id":"8cd227d50f9f079a1e1c300a6419c7172e79f2e8"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"39ff0d82c7df6e919bd7231ca3c7baa1d0426e48","unresolved":false,"context_lines":[{"line_number":141,"context_line":"                So, if the values of actor or target are still None after"},{"line_number":142,"context_line":"                checking kwargs, we can check the positional arguments,"},{"line_number":143,"context_line":"                based on the method signature."},{"line_number":144,"context_line":"                \"\"\""},{"line_number":145,"context_line":""},{"line_number":146,"context_line":"                if \u0027project_id\u0027 in kwargs:"},{"line_number":147,"context_line":"                    target \u003d kwargs.get(\u0027project_id\u0027)"}],"source_content_type":"text/x-python","patch_set":6,"id":"baada198_648193c1","line":144,"updated":"2014-08-10 10:25:02.000000000","message":"Thanks for adding this.  Yuk, but good!","commit_id":"ce735b7a0a6aacecb10b8a92caffaab94960c8bf"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"39ff0d82c7df6e919bd7231ca3c7baa1d0426e48","unresolved":false,"context_lines":[{"line_number":164,"context_line":""},{"line_number":165,"context_line":"                payload \u003d {\u0027resource_info\u0027: {\u0027actor\u0027: actor,"},{"line_number":166,"context_line":"                                             \u0027resource_id\u0027: role_id,"},{"line_number":167,"context_line":"                                             \u0027target\u0027: target}"},{"line_number":168,"context_line":"                           }"},{"line_number":169,"context_line":"                _send_notification(self.operation, \u0027role_assignment\u0027, payload)"},{"line_number":170,"context_line":"            return result"}],"source_content_type":"text/x-python","patch_set":6,"id":"baada198_a4664b53","line":167,"updated":"2014-08-10 10:25:02.000000000","message":"is there a reason we don\u0027t add the inherited_to_projects value to the payload?  Without it, there is no way of knowing of this (domain) assignment affects child projects?","commit_id":"ce735b7a0a6aacecb10b8a92caffaab94960c8bf"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"6c9e5c5f244bc6342fe3a274d2bb756dcb67e43e","unresolved":false,"context_lines":[{"line_number":164,"context_line":""},{"line_number":165,"context_line":"                payload \u003d {\u0027resource_info\u0027: {\u0027actor\u0027: actor,"},{"line_number":166,"context_line":"                                             \u0027resource_id\u0027: role_id,"},{"line_number":167,"context_line":"                                             \u0027target\u0027: target}"},{"line_number":168,"context_line":"                           }"},{"line_number":169,"context_line":"                _send_notification(self.operation, \u0027role_assignment\u0027, payload)"},{"line_number":170,"context_line":"            return result"}],"source_content_type":"text/x-python","patch_set":6,"id":"baada198_b0d4c1bb","line":167,"in_reply_to":"baada198_a4664b53","updated":"2014-08-10 19:42:17.000000000","message":"ugh... yes, it should definitely be part of the payload. next patch will have it","commit_id":"ce735b7a0a6aacecb10b8a92caffaab94960c8bf"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"90fe6235e961348512111447ee069eec1fc649c3","unresolved":false,"context_lines":[{"line_number":108,"context_line":"            \"\"\"Send a notification if the wrapped callable is successful.\"\"\""},{"line_number":109,"context_line":"            try:"},{"line_number":110,"context_line":"                result \u003d f(wrapped_self, role_id, *args, **kwargs)"},{"line_number":111,"context_line":"            except Exception:"},{"line_number":112,"context_line":"                raise"},{"line_number":113,"context_line":"            else:"},{"line_number":114,"context_line":"                \"\"\" NOTE(stevemar): The reason we go through checking kwargs"}],"source_content_type":"text/x-python","patch_set":7,"id":"baada198_c7c7683c","line":111,"updated":"2014-08-13 02:21:03.000000000","message":"Why catch here just to raise?","commit_id":"37ebd074c24c7fb0df47fca34081382422c9ee0d"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"90fe6235e961348512111447ee069eec1fc649c3","unresolved":false,"context_lines":[{"line_number":143,"context_line":"                target \u003d None"},{"line_number":144,"context_line":""},{"line_number":145,"context_line":"                if \u0027project_id\u0027 in kwargs:"},{"line_number":146,"context_line":"                    target \u003d kwargs.get(\u0027project_id\u0027)"},{"line_number":147,"context_line":"                elif \u0027domain_id\u0027 in kwargs:"},{"line_number":148,"context_line":"                    target \u003d kwargs.get(\u0027domain_id\u0027)"},{"line_number":149,"context_line":"                if \u0027user_id\u0027 in kwargs:"}],"source_content_type":"text/x-python","patch_set":7,"id":"baada198_87e730ab","line":146,"updated":"2014-08-13 02:21:03.000000000","message":"You could access these directly because you already make sure the value exists.","commit_id":"37ebd074c24c7fb0df47fca34081382422c9ee0d"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"90fe6235e961348512111447ee069eec1fc649c3","unresolved":false,"context_lines":[{"line_number":156,"context_line":"                    if actor is None:"},{"line_number":157,"context_line":"                        actor \u003d args[1]"},{"line_number":158,"context_line":""},{"line_number":159,"context_line":"                if target is None:"},{"line_number":160,"context_line":"                    target \u003d args[2]"},{"line_number":161,"context_line":"                    if target is None:"},{"line_number":162,"context_line":"                        target \u003d args[3]"}],"source_content_type":"text/x-python","patch_set":7,"id":"baada198_39e919ac","line":159,"updated":"2014-08-13 02:21:03.000000000","message":"The order here doesn\u0027t match the order above. This looks to domain_id and then project_id for the target. The block on line 145 looks at project_id and then domain_id.","commit_id":"37ebd074c24c7fb0df47fca34081382422c9ee0d"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"7506b1f5a28cbe67bf9544edb4ebc78cde1749ce","unresolved":false,"context_lines":[{"line_number":138,"context_line":"            checking kwargs, we can check the positional arguments,"},{"line_number":139,"context_line":"            based on the method signature."},{"line_number":140,"context_line":"            \"\"\""},{"line_number":141,"context_line":"            call_args \u003d inspect.getcallargs("},{"line_number":142,"context_line":"                f, wrapped_self, role_id, *args, **kwargs)"},{"line_number":143,"context_line":"            target \u003d call_args[\u0027project_id\u0027] or call_args[\u0027domain_id\u0027]"},{"line_number":144,"context_line":"            actor \u003d call_args[\u0027user_id\u0027] or call_args[\u0027group_id\u0027]"}],"source_content_type":"text/x-python","patch_set":8,"id":"baada198_69c1f12f","line":141,"updated":"2014-08-13 11:18:42.000000000","message":"this is nice....but I fear this is python 2.7 onwards and not supported in 2.6","commit_id":"4e5bb2370584e459a0d868ffe8483ad0b3895bee"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"f43e3ca4ea2457c2dc11733261ec16e75e6b0424","unresolved":false,"context_lines":[{"line_number":138,"context_line":"            checking kwargs, we can check the positional arguments,"},{"line_number":139,"context_line":"            based on the method signature."},{"line_number":140,"context_line":"            \"\"\""},{"line_number":141,"context_line":"            call_args \u003d inspect.getcallargs("},{"line_number":142,"context_line":"                f, wrapped_self, role_id, *args, **kwargs)"},{"line_number":143,"context_line":"            target \u003d call_args[\u0027project_id\u0027] or call_args[\u0027domain_id\u0027]"},{"line_number":144,"context_line":"            actor \u003d call_args[\u0027user_id\u0027] or call_args[\u0027group_id\u0027]"}],"source_content_type":"text/x-python","patch_set":8,"id":"baada198_6f172e47","line":141,"in_reply_to":"baada198_69c1f12f","updated":"2014-08-13 13:09:39.000000000","message":"There is actually an impl in oslo. Started working on a new patch last night,  but decided to sleep instead :-)","commit_id":"4e5bb2370584e459a0d868ffe8483ad0b3895bee"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"d6b3a2167b2394284fe39c56f80cc63dc6444490","unresolved":false,"context_lines":[{"line_number":174,"context_line":"                }"},{"line_number":175,"context_line":"            }"},{"line_number":176,"context_line":""},{"line_number":177,"context_line":"            _send_notification(self.operation, \u0027role_assignment\u0027, payload)"},{"line_number":178,"context_line":"            return result"},{"line_number":179,"context_line":""},{"line_number":180,"context_line":"        return wrapper"}],"source_content_type":"text/x-python","patch_set":10,"id":"baada198_9bc8394f","line":177,"updated":"2014-08-13 18:48:59.000000000","message":"i think i might have to use the cadf notification, not the normal one","commit_id":"58d58cb249e78b284e6468f0b2abd50399a85db4"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"cd416e896399701bb3f119c2e6358b5f63e4fdf5","unresolved":false,"context_lines":[{"line_number":48,"context_line":"CONF \u003d cfg.CONF"},{"line_number":49,"context_line":"CONF.register_opts(notifier_opts)"},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"try:  # Python 2.7+"},{"line_number":52,"context_line":"    getcallargs \u003d inspect.getcallargs"},{"line_number":53,"context_line":"except AttributeError:  # Python 2.6 support"},{"line_number":54,"context_line":"    def getcallargs(f, *positional, **named):"}],"source_content_type":"text/x-python","patch_set":12,"id":"7ac7a964_5fc5808c","line":51,"updated":"2014-08-16 07:18:48.000000000","message":"I think I can remove this now, as I\u0027ve updated the tests to always use callable args","commit_id":"749043e8aff79b4530edc3f916c3b6ac21edfb0f"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"cd416e896399701bb3f119c2e6358b5f63e4fdf5","unresolved":false,"context_lines":[{"line_number":313,"context_line":""},{"line_number":314,"context_line":"            result \u003d f(wrapped_self, context, role_id, *args, **kwargs)"},{"line_number":315,"context_line":""},{"line_number":316,"context_line":"            \"\"\" NOTE(stevemar): The reason we go through checking kwargs"},{"line_number":317,"context_line":"            and args for possible target and actor values is because the"},{"line_number":318,"context_line":"            create_grant() (and delete_grant()) method are called"},{"line_number":319,"context_line":"            differently in various tests."}],"source_content_type":"text/x-python","patch_set":12,"id":"7ac7a964_7fc07c7c","line":316,"updated":"2014-08-16 07:18:48.000000000","message":"I think I can remove this now, as I\u0027ve updated the tests to always use callable args, we can probably just use kwargs now","commit_id":"749043e8aff79b4530edc3f916c3b6ac21edfb0f"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"2edd8b827eaeb202e627854ea9da5ecfceb284d7","unresolved":false,"context_lines":[{"line_number":432,"context_line":"emit_event \u003d CadfNotificationWrapper"},{"line_number":433,"context_line":""},{"line_number":434,"context_line":""},{"line_number":435,"context_line":"role_assignment \u003d CadfRoleAssignmentNotificationWrapper"}],"source_content_type":"text/x-python","patch_set":20,"id":"1abeadc6_bc6e0595","line":435,"updated":"2014-08-17 11:07:58.000000000","message":"so I know that we don\u0027t like to have too much checking on what the action is inside these notification managers....but it seems odd that we have a general purpose \"emit_event\" which takes an action parameter (i.e. \u0027authenticate\u0027), but then we declare separate one for this action.  If we do keep it separate, then maybe it should be \"emit_role_assignment_event\"","commit_id":"edddb07860c00963c63d85d013ed27dd6c4029e8"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"6007940623ad0c3579a865f95a432a5091c8a572","unresolved":false,"context_lines":[{"line_number":432,"context_line":"emit_event \u003d CadfNotificationWrapper"},{"line_number":433,"context_line":""},{"line_number":434,"context_line":""},{"line_number":435,"context_line":"role_assignment \u003d CadfRoleAssignmentNotificationWrapper"}],"source_content_type":"text/x-python","patch_set":20,"id":"1abeadc6_3c659545","line":435,"in_reply_to":"1abeadc6_bc6e0595","updated":"2014-08-17 13:02:43.000000000","message":"I can certainly change this to emit_role_assignment_event.\n\nThe reason it\u0027s completely separate, is because even though emit_event sounds general purpose, the fact is, these are wrappers, and the signature expects a very specific format:\n\n  def wrapper(wrapped_self, context, user_id, *args, **kwargs):\n\nIf anything, the general purpose one should be renamed to something like emit_authentication_event, and drop the authentication action.","commit_id":"edddb07860c00963c63d85d013ed27dd6c4029e8"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"7fb6beb30788a51636ee4f144788ae02ec2576cd","unresolved":false,"context_lines":[{"line_number":275,"context_line":"                http_user_agent \u003d environment.get(\u0027HTTP_USER_AGENT\u0027)"},{"line_number":276,"context_line":""},{"line_number":277,"context_line":"            host \u003d pycadf.host.Host(address\u003dremote_addr, agent\u003dhttp_user_agent)"},{"line_number":278,"context_line":"            initiator \u003d resource.Resource(typeURI\u003dtaxonomy.ACCOUNT_USER,"},{"line_number":279,"context_line":"                                          name\u003duser_id, host\u003dhost)"},{"line_number":280,"context_line":""},{"line_number":281,"context_line":"            _send_audit_notification(self.action, initiator,"}],"source_content_type":"text/x-python","patch_set":24,"id":"1abeadc6_4958a732","line":278,"updated":"2014-08-18 20:04:10.000000000","message":"is this wrong? in the code below the user_id is from the environment.","commit_id":"75fd871b0e056b72be457c1e8f5bbf3838439258"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"6c158a55d196741d5ed8ce45bca2997a3321a228","unresolved":false,"context_lines":[{"line_number":275,"context_line":"                http_user_agent \u003d environment.get(\u0027HTTP_USER_AGENT\u0027)"},{"line_number":276,"context_line":""},{"line_number":277,"context_line":"            host \u003d pycadf.host.Host(address\u003dremote_addr, agent\u003dhttp_user_agent)"},{"line_number":278,"context_line":"            initiator \u003d resource.Resource(typeURI\u003dtaxonomy.ACCOUNT_USER,"},{"line_number":279,"context_line":"                                          name\u003duser_id, host\u003dhost)"},{"line_number":280,"context_line":""},{"line_number":281,"context_line":"            _send_audit_notification(self.action, initiator,"}],"source_content_type":"text/x-python","patch_set":24,"id":"1abeadc6_293d2b90","line":278,"in_reply_to":"1abeadc6_4958a732","updated":"2014-08-18 20:10:51.000000000","message":"no, in the case of auditing authN, the manger\u0027s actually have user_id as a parameter, so we use that one.","commit_id":"75fd871b0e056b72be457c1e8f5bbf3838439258"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"7fb6beb30788a51636ee4f144788ae02ec2576cd","unresolved":false,"context_lines":[{"line_number":301,"context_line":"    Sends a CADF notification if the wrapped method does not raise an"},{"line_number":302,"context_line":"    ``Exception`` (such as ``keystone.exception.NotFound``)."},{"line_number":303,"context_line":""},{"line_number":304,"context_line":"    :param operation:  one of the values from ACTIONS (create or delete)"},{"line_number":305,"context_line":"    \"\"\""},{"line_number":306,"context_line":""},{"line_number":307,"context_line":"    def __init__(self, operation):"}],"source_content_type":"text/x-python","patch_set":24,"id":"1abeadc6_a5dde116","line":304,"updated":"2014-08-18 20:04:10.000000000","message":"there\u0027s an extra space here between : and one","commit_id":"75fd871b0e056b72be457c1e8f5bbf3838439258"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"6c158a55d196741d5ed8ce45bca2997a3321a228","unresolved":false,"context_lines":[{"line_number":301,"context_line":"    Sends a CADF notification if the wrapped method does not raise an"},{"line_number":302,"context_line":"    ``Exception`` (such as ``keystone.exception.NotFound``)."},{"line_number":303,"context_line":""},{"line_number":304,"context_line":"    :param operation:  one of the values from ACTIONS (create or delete)"},{"line_number":305,"context_line":"    \"\"\""},{"line_number":306,"context_line":""},{"line_number":307,"context_line":"    def __init__(self, operation):"}],"source_content_type":"text/x-python","patch_set":24,"id":"1abeadc6_69472320","line":304,"in_reply_to":"1abeadc6_a5dde116","updated":"2014-08-18 20:10:51.000000000","message":"Done","commit_id":"75fd871b0e056b72be457c1e8f5bbf3838439258"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"7fb6beb30788a51636ee4f144788ae02ec2576cd","unresolved":false,"context_lines":[{"line_number":353,"context_line":""},{"line_number":354,"context_line":"            if context and context.get(\u0027environment\u0027):"},{"line_number":355,"context_line":"                environment \u003d context[\u0027environment\u0027]"},{"line_number":356,"context_line":"                remote_addr \u003d environment.get(\u0027REMOTE_ADDR\u0027)"},{"line_number":357,"context_line":"                http_user_agent \u003d environment.get(\u0027HTTP_USER_AGENT\u0027)"},{"line_number":358,"context_line":"                auth_context \u003d environment.get(\u0027KEYSTONE_AUTH_CONTEXT\u0027)"},{"line_number":359,"context_line":"                user_id \u003d auth_context.get(\u0027user_id\u0027)"}],"source_content_type":"text/x-python","patch_set":24,"id":"1abeadc6_e948935d","line":356,"updated":"2014-08-18 20:04:10.000000000","message":"the code to get the remote_addr, http_user_agent, and user_id from the request environment should be able to be shared with CadfNotificationWrapper. Put it in a function and share it.","commit_id":"75fd871b0e056b72be457c1e8f5bbf3838439258"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"6c158a55d196741d5ed8ce45bca2997a3321a228","unresolved":false,"context_lines":[{"line_number":353,"context_line":""},{"line_number":354,"context_line":"            if context and context.get(\u0027environment\u0027):"},{"line_number":355,"context_line":"                environment \u003d context[\u0027environment\u0027]"},{"line_number":356,"context_line":"                remote_addr \u003d environment.get(\u0027REMOTE_ADDR\u0027)"},{"line_number":357,"context_line":"                http_user_agent \u003d environment.get(\u0027HTTP_USER_AGENT\u0027)"},{"line_number":358,"context_line":"                auth_context \u003d environment.get(\u0027KEYSTONE_AUTH_CONTEXT\u0027)"},{"line_number":359,"context_line":"                user_id \u003d auth_context.get(\u0027user_id\u0027)"}],"source_content_type":"text/x-python","patch_set":24,"id":"1abeadc6_a96f7b91","line":356,"in_reply_to":"1abeadc6_e948935d","updated":"2014-08-18 20:10:51.000000000","message":"I can do that for remote_addr and http_user_agent. Refer to my other answer re: user_id","commit_id":"75fd871b0e056b72be457c1e8f5bbf3838439258"},{"author":{"_account_id":6537,"name":"gordon chung","email":"gord@live.ca","username":"chungg"},"change_message_id":"eb2b36248f04efc26d40d380c53ee1eb95def677","unresolved":false,"context_lines":[{"line_number":269,"context_line":"            remote_addr \u003d None"},{"line_number":270,"context_line":"            http_user_agent \u003d None"},{"line_number":271,"context_line":""},{"line_number":272,"context_line":"            if context and \u0027environment\u0027 in context:"},{"line_number":273,"context_line":"                result \u003d _get_request_details(context)"},{"line_number":274,"context_line":"                (remote_addr, http_user_agent, _auth_context) \u003d result"},{"line_number":275,"context_line":""}],"source_content_type":"text/x-python","patch_set":25,"id":"1abeadc6_a0d5a1ba","line":272,"updated":"2014-08-19 18:17:15.000000000","message":"you can probably move this check into method since it\u0027s reused?","commit_id":"5fb17fda3225c9c71f9b71649e4ca8381cde6537"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"ca6fdd3eaa95436d9404dc7f59c7bdcd388344a1","unresolved":false,"context_lines":[{"line_number":269,"context_line":"            remote_addr \u003d None"},{"line_number":270,"context_line":"            http_user_agent \u003d None"},{"line_number":271,"context_line":""},{"line_number":272,"context_line":"            if context and \u0027environment\u0027 in context:"},{"line_number":273,"context_line":"                result \u003d _get_request_details(context)"},{"line_number":274,"context_line":"                (remote_addr, http_user_agent, _auth_context) \u003d result"},{"line_number":275,"context_line":""}],"source_content_type":"text/x-python","patch_set":25,"id":"1abeadc6_2b5a48f3","line":272,"in_reply_to":"1abeadc6_a0d5a1ba","updated":"2014-08-19 22:46:26.000000000","message":"Done","commit_id":"5fb17fda3225c9c71f9b71649e4ca8381cde6537"},{"author":{"_account_id":6537,"name":"gordon chung","email":"gord@live.ca","username":"chungg"},"change_message_id":"eb2b36248f04efc26d40d380c53ee1eb95def677","unresolved":false,"context_lines":[{"line_number":271,"context_line":""},{"line_number":272,"context_line":"            if context and \u0027environment\u0027 in context:"},{"line_number":273,"context_line":"                result \u003d _get_request_details(context)"},{"line_number":274,"context_line":"                (remote_addr, http_user_agent, _auth_context) \u003d result"},{"line_number":275,"context_line":""},{"line_number":276,"context_line":"            host \u003d pycadf.host.Host(address\u003dremote_addr, agent\u003dhttp_user_agent)"},{"line_number":277,"context_line":"            initiator \u003d resource.Resource(typeURI\u003dtaxonomy.ACCOUNT_USER,"}],"source_content_type":"text/x-python","patch_set":25,"id":"1abeadc6_808425d5","line":274,"updated":"2014-08-19 18:17:15.000000000","message":"you can use __ for _auth_context if you never intend on using it.","commit_id":"5fb17fda3225c9c71f9b71649e4ca8381cde6537"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"ca6fdd3eaa95436d9404dc7f59c7bdcd388344a1","unresolved":false,"context_lines":[{"line_number":271,"context_line":""},{"line_number":272,"context_line":"            if context and \u0027environment\u0027 in context:"},{"line_number":273,"context_line":"                result \u003d _get_request_details(context)"},{"line_number":274,"context_line":"                (remote_addr, http_user_agent, _auth_context) \u003d result"},{"line_number":275,"context_line":""},{"line_number":276,"context_line":"            host \u003d pycadf.host.Host(address\u003dremote_addr, agent\u003dhttp_user_agent)"},{"line_number":277,"context_line":"            initiator \u003d resource.Resource(typeURI\u003dtaxonomy.ACCOUNT_USER,"}],"source_content_type":"text/x-python","patch_set":25,"id":"1abeadc6_0b63ccb1","line":274,"in_reply_to":"1abeadc6_808425d5","updated":"2014-08-19 22:46:26.000000000","message":"we usually settle on just prefixing it with an underscore, but i\u0027ll do it your way, just this one time :)","commit_id":"5fb17fda3225c9c71f9b71649e4ca8381cde6537"},{"author":{"_account_id":6537,"name":"gordon chung","email":"gord@live.ca","username":"chungg"},"change_message_id":"eb2b36248f04efc26d40d380c53ee1eb95def677","unresolved":false,"context_lines":[{"line_number":368,"context_line":"                                          name\u003duser_id, host\u003dhost)"},{"line_number":369,"context_line":""},{"line_number":370,"context_line":"            attach_uri \u003d \u0027attachURI\u0027"},{"line_number":371,"context_line":"            actor_attach \u003d attachment.Attachment(typeURI\u003dattach_uri,"},{"line_number":372,"context_line":"                                                 content\u003dactor,"},{"line_number":373,"context_line":"                                                 name\u003d\u0027actor\u0027)"},{"line_number":374,"context_line":"            target_attach \u003d attachment.Attachment(typeURI\u003dattach_uri,"}],"source_content_type":"text/x-python","patch_set":25,"id":"1abeadc6_1ba9647b","line":371,"updated":"2014-08-19 18:17:15.000000000","message":"hmm.. interesting... this should fail since contentType is a required field. guess the validation isn\u0027t being triggered.\n\nthat said, i\u0027m not sure we need attachements. attachments iiuc are more for say something like a jpeg, doc, etc... if you\u0027re just adding an attribute you could just add it to event like you would typical attribute... ie.  initiator.role \u003d value\n\nalternatively, you can extend either Event or Resource and add those attributes in if you want to formalise/validate it: https://github.com/openstack/pycadf/blob/master/pycadf/audit/api.py#L93-L97","commit_id":"5fb17fda3225c9c71f9b71649e4ca8381cde6537"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"ca6fdd3eaa95436d9404dc7f59c7bdcd388344a1","unresolved":false,"context_lines":[{"line_number":368,"context_line":"                                          name\u003duser_id, host\u003dhost)"},{"line_number":369,"context_line":""},{"line_number":370,"context_line":"            attach_uri \u003d \u0027attachURI\u0027"},{"line_number":371,"context_line":"            actor_attach \u003d attachment.Attachment(typeURI\u003dattach_uri,"},{"line_number":372,"context_line":"                                                 content\u003dactor,"},{"line_number":373,"context_line":"                                                 name\u003d\u0027actor\u0027)"},{"line_number":374,"context_line":"            target_attach \u003d attachment.Attachment(typeURI\u003dattach_uri,"}],"source_content_type":"text/x-python","patch_set":25,"id":"1abeadc6_cb4554b4","line":371,"in_reply_to":"1abeadc6_1ba9647b","updated":"2014-08-19 22:46:26.000000000","message":"++ I just made the properties, didn\u0027t know we could do that, that\u0027s awesome, thanks gordon!","commit_id":"5fb17fda3225c9c71f9b71649e4ca8381cde6537"},{"author":{"_account_id":6537,"name":"gordon chung","email":"gord@live.ca","username":"chungg"},"change_message_id":"eb2b36248f04efc26d40d380c53ee1eb95def677","unresolved":false,"context_lines":[{"line_number":390,"context_line":"            _send_audit_notification(self.operation, initiator,"},{"line_number":391,"context_line":"                                     taxonomy.OUTCOME_SUCCESS)"},{"line_number":392,"context_line":""},{"line_number":393,"context_line":"            return result"},{"line_number":394,"context_line":""},{"line_number":395,"context_line":"        return wrapper"},{"line_number":396,"context_line":""}],"source_content_type":"text/x-python","patch_set":25,"id":"1abeadc6_fbc4a841","line":393,"updated":"2014-08-19 18:17:15.000000000","message":"do you forsee any errors being triggered? if so, i\u0027d wrap everything in a generic try/catch... i don\u0027t think we want errors in auditing to affect the normal api request.","commit_id":"5fb17fda3225c9c71f9b71649e4ca8381cde6537"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"ca6fdd3eaa95436d9404dc7f59c7bdcd388344a1","unresolved":false,"context_lines":[{"line_number":390,"context_line":"            _send_audit_notification(self.operation, initiator,"},{"line_number":391,"context_line":"                                     taxonomy.OUTCOME_SUCCESS)"},{"line_number":392,"context_line":""},{"line_number":393,"context_line":"            return result"},{"line_number":394,"context_line":""},{"line_number":395,"context_line":"        return wrapper"},{"line_number":396,"context_line":""}],"source_content_type":"text/x-python","patch_set":25,"id":"1abeadc6_2bb6c8fa","line":393,"in_reply_to":"1abeadc6_fbc4a841","updated":"2014-08-19 22:46:26.000000000","message":"there shouldn\u0027t be any errors, but i\u0027ll wrap it just in case.","commit_id":"5fb17fda3225c9c71f9b71649e4ca8381cde6537"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"aa44ce72f3f3a603edda1fa1500b7454e04eb342","unresolved":false,"context_lines":[{"line_number":406,"context_line":"        taxonomy.OUTCOME_SUCCESS, taxonomy.OUTCOME_FAILURE)"},{"line_number":407,"context_line":""},{"line_number":408,"context_line":"    \"\"\""},{"line_number":409,"context_line":""},{"line_number":410,"context_line":"    event \u003d eventfactory.EventFactory().new_event("},{"line_number":411,"context_line":"        eventType\u003dcadftype.EVENTTYPE_ACTIVITY,"},{"line_number":412,"context_line":"        outcome\u003doutcome,"}],"source_content_type":"text/x-python","patch_set":25,"id":"1abeadc6_be9327f9","line":409,"updated":"2014-08-18 23:57:11.000000000","message":"Just realized that I can also add attachments at the event level, instead of the initiator level.... wondering if the reviewers think that is a better option?","commit_id":"5fb17fda3225c9c71f9b71649e4ca8381cde6537"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"9d42b781220f0c44546032c315908dc0d8cf28ac","unresolved":false,"context_lines":[{"line_number":406,"context_line":"        taxonomy.OUTCOME_SUCCESS, taxonomy.OUTCOME_FAILURE)"},{"line_number":407,"context_line":""},{"line_number":408,"context_line":"    \"\"\""},{"line_number":409,"context_line":""},{"line_number":410,"context_line":"    event \u003d eventfactory.EventFactory().new_event("},{"line_number":411,"context_line":"        eventType\u003dcadftype.EVENTTYPE_ACTIVITY,"},{"line_number":412,"context_line":"        outcome\u003doutcome,"}],"source_content_type":"text/x-python","patch_set":25,"id":"1abeadc6_d2c5375c","line":409,"in_reply_to":"1abeadc6_be9327f9","updated":"2014-08-19 00:23:24.000000000","message":"I think it\u0027s best left where it is for now. This is mostly because this function is already used by other things. If we have to add more attachments or add them to one of the other code paths that call this function my opinion would likely change.","commit_id":"5fb17fda3225c9c71f9b71649e4ca8381cde6537"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"38bf15d847f664514befb3f98b97fab76364cf45","unresolved":false,"context_lines":[{"line_number":379,"context_line":"        return wrapper"},{"line_number":380,"context_line":""},{"line_number":381,"context_line":""},{"line_number":382,"context_line":"def _send_audit_notification(action, initiator, outcome):"},{"line_number":383,"context_line":"    \"\"\"Send CADF notification to inform observers about the affected resource."},{"line_number":384,"context_line":""},{"line_number":385,"context_line":"    This method logs an exception when sending the notification fails."}],"source_content_type":"text/x-python","patch_set":26,"id":"1abeadc6_ab9498e2","line":382,"updated":"2014-08-19 22:49:41.000000000","message":"I still think it\u0027s worth noting that we can add attributes to the event, instead of the initiator. We could have **kwargs here,\nand add any kwargs to event (line 400).","commit_id":"aabd46182898cebbbc2e92d9ba4086c56334a424"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"d3667f7c6989088203c8895da7cd0ab5a24b1eab","unresolved":false,"context_lines":[{"line_number":289,"context_line":"        return wrapper"},{"line_number":290,"context_line":""},{"line_number":291,"context_line":""},{"line_number":292,"context_line":"def _get_request_details(context):"},{"line_number":293,"context_line":"    remote_addr \u003d None"},{"line_number":294,"context_line":"    http_user_agent \u003d None"},{"line_number":295,"context_line":"    user_id \u003d None"}],"source_content_type":"text/x-python","patch_set":28,"id":"1abeadc6_fe80e3c1","line":292,"updated":"2014-08-20 21:20:20.000000000","message":"this should be moved up before it\u0027s used.","commit_id":"a6aff0d612082bae8d6fb719f417a664329678ae"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"d3667f7c6989088203c8895da7cd0ab5a24b1eab","unresolved":false,"context_lines":[{"line_number":299,"context_line":"        remote_addr \u003d environment.get(\u0027REMOTE_ADDR\u0027)"},{"line_number":300,"context_line":"        http_user_agent \u003d environment.get(\u0027HTTP_USER_AGENT\u0027)"},{"line_number":301,"context_line":"        user_id \u003d environment.get(\u0027KEYSTONE_AUTH_CONTEXT\u0027, {}).get(\u0027user_id\u0027)"},{"line_number":302,"context_line":"    return (remote_addr, http_user_agent, user_id)"},{"line_number":303,"context_line":""},{"line_number":304,"context_line":""},{"line_number":305,"context_line":"class CadfRoleAssignmentNotificationWrapper(object):"}],"source_content_type":"text/x-python","patch_set":28,"id":"1abeadc6_def08769","line":302,"updated":"2014-08-20 21:20:20.000000000","message":"This could build the host and initiator since that\u0027s the same. Pass in the user_id and use that if it\u0027s given:\n\ndef _get_request_audit_info(context, user_id\u003dNone):\n   ....\n       if not user_id:\n          user_id \u003d environment.get(...\n\n   host \u003d pycadf.host.Host(address\u003dremote_addr, agent\u003dhttp_user_agent)\n   initiator \u003d resource.Resource(typeURI\u003dtaxonomy.ACCOUNT_USER, ... )\n\n   return host, initiator","commit_id":"a6aff0d612082bae8d6fb719f417a664329678ae"},{"author":{"_account_id":6537,"name":"gordon chung","email":"gord@live.ca","username":"chungg"},"change_message_id":"0ea02f964d066b0e63ef4e50a0d5592ffe734017","unresolved":false,"context_lines":[{"line_number":362,"context_line":"            initiator.actor \u003d actor"},{"line_number":363,"context_line":"            initiator.target \u003d target"},{"line_number":364,"context_line":"            initiator.inherited_to_projects \u003d inherited"},{"line_number":365,"context_line":"            initiator.role \u003d role_id"},{"line_number":366,"context_line":""},{"line_number":367,"context_line":"            try:"},{"line_number":368,"context_line":"                result \u003d f(wrapped_self, role_id, *args, **kwargs)"}],"source_content_type":"text/x-python","patch_set":28,"id":"1abeadc6_5f21e8f9","line":365,"updated":"2014-08-20 12:45:34.000000000","message":"whoops sorry. i meant wrapping the auditing part. ie. building host, getting request details, everything above. just so if the auditing part fails, the request will still continue on as normal ie. f(wrapped_self, role_id, *args, **kwargs) still gets called and returned","commit_id":"a6aff0d612082bae8d6fb719f417a664329678ae"},{"author":{"_account_id":6537,"name":"gordon chung","email":"gord@live.ca","username":"chungg"},"change_message_id":"95f8fb9bd0e45de0b1dc171424a030e3c0893fb5","unresolved":false,"context_lines":[{"line_number":362,"context_line":"            initiator.actor \u003d actor"},{"line_number":363,"context_line":"            initiator.target \u003d target"},{"line_number":364,"context_line":"            initiator.inherited_to_projects \u003d inherited"},{"line_number":365,"context_line":"            initiator.role \u003d role_id"},{"line_number":366,"context_line":""},{"line_number":367,"context_line":"            try:"},{"line_number":368,"context_line":"                result \u003d f(wrapped_self, role_id, *args, **kwargs)"}],"source_content_type":"text/x-python","patch_set":28,"id":"1abeadc6_92b8d2c9","line":365,"in_reply_to":"1abeadc6_5f21e8f9","updated":"2014-08-20 15:07:20.000000000","message":"i spoke with Steve. we\u0027ve concluded that the above code won\u0027t throw any unforeseen errors so we can ignore my comment regarding adding try/except blocks. please carry on with your regularly scheduled plan","commit_id":"a6aff0d612082bae8d6fb719f417a664329678ae"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"6031a71292bfbeb1b615e185c1963b9c42747937","unresolved":false,"context_lines":[{"line_number":289,"context_line":"        return wrapper"},{"line_number":290,"context_line":""},{"line_number":291,"context_line":""},{"line_number":292,"context_line":"def _get_request_details(context):"},{"line_number":293,"context_line":"    remote_addr \u003d None"},{"line_number":294,"context_line":"    http_user_agent \u003d None"},{"line_number":295,"context_line":"    user_id \u003d None"}],"source_content_type":"text/x-python","patch_set":29,"id":"1abeadc6_c1742738","line":292,"updated":"2014-08-21 00:43:14.000000000","message":"this should be moved up before it\u0027s used.","commit_id":"2f0f843e17d3ba9043dddc14346c284af79dedaf"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"b25c899b6a4cccc02f34391bd4ab18da9f77d17a","unresolved":false,"context_lines":[{"line_number":289,"context_line":"        return wrapper"},{"line_number":290,"context_line":""},{"line_number":291,"context_line":""},{"line_number":292,"context_line":"def _get_request_details(context):"},{"line_number":293,"context_line":"    remote_addr \u003d None"},{"line_number":294,"context_line":"    http_user_agent \u003d None"},{"line_number":295,"context_line":"    user_id \u003d None"}],"source_content_type":"text/x-python","patch_set":29,"id":"1abeadc6_8d017e3a","line":292,"in_reply_to":"1abeadc6_c1742738","updated":"2014-08-21 04:20:15.000000000","message":"Done","commit_id":"2f0f843e17d3ba9043dddc14346c284af79dedaf"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"6031a71292bfbeb1b615e185c1963b9c42747937","unresolved":false,"context_lines":[{"line_number":299,"context_line":"        remote_addr \u003d environment.get(\u0027REMOTE_ADDR\u0027)"},{"line_number":300,"context_line":"        http_user_agent \u003d environment.get(\u0027HTTP_USER_AGENT\u0027)"},{"line_number":301,"context_line":"        user_id \u003d environment.get(\u0027KEYSTONE_AUTH_CONTEXT\u0027, {}).get(\u0027user_id\u0027)"},{"line_number":302,"context_line":"    return (remote_addr, http_user_agent, user_id)"},{"line_number":303,"context_line":""},{"line_number":304,"context_line":""},{"line_number":305,"context_line":"class CadfRoleAssignmentNotificationWrapper(object):"}],"source_content_type":"text/x-python","patch_set":29,"id":"1abeadc6_e1712345","line":302,"updated":"2014-08-21 00:43:14.000000000","message":"This could build the host and initiator since that\u0027s the same. Pass in the user_id and use that if it\u0027s given:\n\n def _get_request_audit_info(context, user_id\u003dNone):\n     ....\n         if not user_id:\n             user_id \u003d environment.get(...\n\n     host \u003d pycadf.host.Host(address\u003dremote_addr, agent\u003dhttp_user_agent)\n     initiator \u003d resource.Resource(typeURI\u003dtaxonomy.ACCOUNT_USER, ... )\n\n     return host, initiator","commit_id":"2f0f843e17d3ba9043dddc14346c284af79dedaf"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"b25c899b6a4cccc02f34391bd4ab18da9f77d17a","unresolved":false,"context_lines":[{"line_number":299,"context_line":"        remote_addr \u003d environment.get(\u0027REMOTE_ADDR\u0027)"},{"line_number":300,"context_line":"        http_user_agent \u003d environment.get(\u0027HTTP_USER_AGENT\u0027)"},{"line_number":301,"context_line":"        user_id \u003d environment.get(\u0027KEYSTONE_AUTH_CONTEXT\u0027, {}).get(\u0027user_id\u0027)"},{"line_number":302,"context_line":"    return (remote_addr, http_user_agent, user_id)"},{"line_number":303,"context_line":""},{"line_number":304,"context_line":""},{"line_number":305,"context_line":"class CadfRoleAssignmentNotificationWrapper(object):"}],"source_content_type":"text/x-python","patch_set":29,"id":"1abeadc6_4dba066f","line":302,"in_reply_to":"1abeadc6_e1712345","updated":"2014-08-21 04:20:15.000000000","message":"actually, just need to return the initiator, but ++","commit_id":"2f0f843e17d3ba9043dddc14346c284af79dedaf"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"d5a1435e371cea4a5ec8b2e3ef329e8c471f3c7b","unresolved":false,"context_lines":[{"line_number":16,"context_line":""},{"line_number":17,"context_line":"import inspect"},{"line_number":18,"context_line":"import logging"},{"line_number":19,"context_line":"import six"},{"line_number":20,"context_line":"import socket"},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"from oslo.config import cfg"}],"source_content_type":"text/x-python","patch_set":31,"id":"1abeadc6_0b09b52b","line":19,"updated":"2014-08-21 21:55:17.000000000","message":"This is a third-party module.","commit_id":"cc4f9e072d95b8ccc284d5e377fece299a3a0eb2"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"f76114d2b6c5befbd17ed93f101f6486d8fb9ead","unresolved":false,"context_lines":[{"line_number":365,"context_line":""},{"line_number":366,"context_line":"            extra_params[\u0027inherited_to_projects\u0027] \u003d inherited"},{"line_number":367,"context_line":"            extra_params[\u0027role\u0027] \u003d role_id"},{"line_number":368,"context_line":""},{"line_number":369,"context_line":"            try:"},{"line_number":370,"context_line":"                result \u003d f(wrapped_self, role_id, *args, **kwargs)"},{"line_number":371,"context_line":"            except Exception:"}],"source_content_type":"text/x-python","patch_set":32,"id":"1abeadc6_54fb4a78","line":368,"updated":"2014-08-22 00:13:13.000000000","message":"isn\u0027t there supposed to be an OUTCOME_PENDING notification?","commit_id":"1b2a51e49e6e8fc69cfe20289284c055914b0891"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"82941309803164b6b7b37795135648c2881c199a","unresolved":false,"context_lines":[{"line_number":365,"context_line":""},{"line_number":366,"context_line":"            extra_params[\u0027inherited_to_projects\u0027] \u003d inherited"},{"line_number":367,"context_line":"            extra_params[\u0027role\u0027] \u003d role_id"},{"line_number":368,"context_line":""},{"line_number":369,"context_line":"            try:"},{"line_number":370,"context_line":"                result \u003d f(wrapped_self, role_id, *args, **kwargs)"},{"line_number":371,"context_line":"            except Exception:"}],"source_content_type":"text/x-python","patch_set":32,"id":"1abeadc6_c0df94d4","line":368,"in_reply_to":"1abeadc6_54fb4a78","updated":"2014-08-22 03:44:11.000000000","message":"it seems more important for authN events than role_assignment events.\n\nAlso there will always be a success/failure msg, so i don\u0027t really see *that* much value in it. That being said, if it\u0027s preventing a +2, i\u0027ll include it.","commit_id":"1b2a51e49e6e8fc69cfe20289284c055914b0891"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"f76114d2b6c5befbd17ed93f101f6486d8fb9ead","unresolved":false,"context_lines":[{"line_number":382,"context_line":"        return wrapper"},{"line_number":383,"context_line":""},{"line_number":384,"context_line":""},{"line_number":385,"context_line":"def _send_audit_notification(action, initiator, outcome, extra_params\u003dNone):"},{"line_number":386,"context_line":"    \"\"\"Send CADF notification to inform observers about the affected resource."},{"line_number":387,"context_line":""},{"line_number":388,"context_line":"    This method logs an exception when sending the notification fails."}],"source_content_type":"text/x-python","patch_set":32,"id":"1abeadc6_94da4215","line":385,"updated":"2014-08-22 00:13:13.000000000","message":"seems like kwargs would make sense here.","commit_id":"1b2a51e49e6e8fc69cfe20289284c055914b0891"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"82941309803164b6b7b37795135648c2881c199a","unresolved":false,"context_lines":[{"line_number":382,"context_line":"        return wrapper"},{"line_number":383,"context_line":""},{"line_number":384,"context_line":""},{"line_number":385,"context_line":"def _send_audit_notification(action, initiator, outcome, extra_params\u003dNone):"},{"line_number":386,"context_line":"    \"\"\"Send CADF notification to inform observers about the affected resource."},{"line_number":387,"context_line":""},{"line_number":388,"context_line":"    This method logs an exception when sending the notification fails."}],"source_content_type":"text/x-python","patch_set":32,"id":"1abeadc6_40d464bc","line":385,"in_reply_to":"1abeadc6_94da4215","updated":"2014-08-22 03:44:11.000000000","message":"yeah, i\u0027ll change it over","commit_id":"1b2a51e49e6e8fc69cfe20289284c055914b0891"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"8be378518db3171683aa495e188dbc24beb8635b","unresolved":false,"context_lines":[{"line_number":375,"context_line":"                                         **audit_kwargs)"},{"line_number":376,"context_line":"                raise"},{"line_number":377,"context_line":"            else:"},{"line_number":378,"context_line":"                _send_audit_notification(self.operation, initiator,"},{"line_number":379,"context_line":"                                         taxonomy.OUTCOME_SUCCESS,"},{"line_number":380,"context_line":"                                         **audit_kwargs)"},{"line_number":381,"context_line":"                return result"}],"source_content_type":"text/x-python","patch_set":34,"id":"1abeadc6_f87989c8","line":378,"updated":"2014-08-22 19:17:42.000000000","message":"(suggestion) some duplication could be removed by using functools.partial:\n\n send_notification \u003d functools.partial(self.operation, initiator, **audit_kwargs)\n\n send_notification(taxonomy.OUTCOME_SUCCESS)\n\nand then at line 373, would just be\n\n send_notification(taxonomy.OUTCOME_FAILURE)","commit_id":"a5a17d984375cf9afb9a5f01493db8da23d5e531"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"743f38b52a19967120d5087a0a6c193c6944ba0f","unresolved":false,"context_lines":[{"line_number":403,"context_line":"        target\u003dresource.Resource(typeURI\u003dtaxonomy.ACCOUNT_USER),"},{"line_number":404,"context_line":"        observer\u003dresource.Resource(typeURI\u003dtaxonomy.SERVICE_SECURITY))"},{"line_number":405,"context_line":""},{"line_number":406,"context_line":"    for key, value in kwargs.items():"},{"line_number":407,"context_line":"        setattr(event, key, value)"},{"line_number":408,"context_line":""},{"line_number":409,"context_line":"    context \u003d {}"}],"source_content_type":"text/x-python","patch_set":34,"id":"1abeadc6_052154b4","line":406,"updated":"2014-08-25 11:37:53.000000000","message":"need to use six iteritems here for py3 support","commit_id":"a5a17d984375cf9afb9a5f01493db8da23d5e531"}],"keystone/tests/test_notifications.py":[{"author":{"_account_id":9101,"name":"wanghong","email":"reviewwanghong@126.com","username":"wanghong"},"change_message_id":"b46f2b34e7398250194e49b20154f164b0e333a3","unresolved":false,"context_lines":[{"line_number":213,"context_line":"        else:"},{"line_number":214,"context_line":"            self.fail(\"Notification not sent.\")"},{"line_number":215,"context_line":""},{"line_number":216,"context_line":"    def _assertLastNotifyPayload(self, payload, operation, resource_type):"},{"line_number":217,"context_line":"        self.assertTrue(len(self._notifications) \u003e 0)"},{"line_number":218,"context_line":"        note \u003d self._notifications[-1]"},{"line_number":219,"context_line":"        self.assertEqual(note[\u0027operation\u0027], operation)"}],"source_content_type":"text/x-python","patch_set":3,"id":"baada198_f50bc1d2","line":216,"updated":"2014-08-08 03:34:49.000000000","message":"If move \u0027target\u0027 and \u0027actor\u0027 into resource_info, this method can be removed. Use _assertLastNotify instead.","commit_id":"10112290062a565e35ec9836e81ecaace589bbb8"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"8b6e0bf70f733901120956d44b4d182589751d04","unresolved":false,"context_lines":[{"line_number":213,"context_line":"        else:"},{"line_number":214,"context_line":"            self.fail(\"Notification not sent.\")"},{"line_number":215,"context_line":""},{"line_number":216,"context_line":"    def _assertLastNotifyPayload(self, payload, operation, resource_type):"},{"line_number":217,"context_line":"        self.assertTrue(len(self._notifications) \u003e 0)"},{"line_number":218,"context_line":"        note \u003d self._notifications[-1]"},{"line_number":219,"context_line":"        self.assertEqual(note[\u0027operation\u0027], operation)"}],"source_content_type":"text/x-python","patch_set":3,"id":"baada198_f40bad2a","line":216,"in_reply_to":"baada198_952605ca","updated":"2014-08-08 15:33:21.000000000","message":"I made payload an optional arg to assertLastNotify","commit_id":"10112290062a565e35ec9836e81ecaace589bbb8"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"2ebc0f57531c2b68c85a176016b1b871fb5977e9","unresolved":false,"context_lines":[{"line_number":213,"context_line":"        else:"},{"line_number":214,"context_line":"            self.fail(\"Notification not sent.\")"},{"line_number":215,"context_line":""},{"line_number":216,"context_line":"    def _assertLastNotifyPayload(self, payload, operation, resource_type):"},{"line_number":217,"context_line":"        self.assertTrue(len(self._notifications) \u003e 0)"},{"line_number":218,"context_line":"        note \u003d self._notifications[-1]"},{"line_number":219,"context_line":"        self.assertEqual(note[\u0027operation\u0027], operation)"}],"source_content_type":"text/x-python","patch_set":3,"id":"baada198_952605ca","line":216,"in_reply_to":"baada198_f50bc1d2","updated":"2014-08-08 04:21:32.000000000","message":"i don\u0027t think so, _assertLastNotify still expects only a single ID.","commit_id":"10112290062a565e35ec9836e81ecaace589bbb8"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"abbf8d33c88eb03c43009fa1c07562de36d523f6","unresolved":false,"context_lines":[{"line_number":543,"context_line":"                             \u0027resource_id\u0027: role_ref[\u0027id\u0027],"},{"line_number":544,"context_line":"                             \u0027target\u0027: self.project_id}"},{"line_number":545,"context_line":"           }"},{"line_number":546,"context_line":"        \"\"\""},{"line_number":547,"context_line":""},{"line_number":548,"context_line":"    def test_group_domain_grant(self):"},{"line_number":549,"context_line":"        role_ref \u003d self.new_role_ref()"}],"source_content_type":"text/x-python","patch_set":11,"id":"7ac7a964_0bd5911b","line":546,"updated":"2014-08-15 22:33:29.000000000","message":"assert the actor/role/target are actually in the initiator\u0027s attachment payload","commit_id":"c636cce6d968a3aa3c12567ab6b3d563b0cc37dc"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"cd416e896399701bb3f119c2e6358b5f63e4fdf5","unresolved":false,"context_lines":[{"line_number":30,"context_line":"CREATED_OPERATION \u003d \u0027created\u0027"},{"line_number":31,"context_line":"UPDATED_OPERATION \u003d \u0027updated\u0027"},{"line_number":32,"context_line":"DELETED_OPERATION \u003d \u0027deleted\u0027"},{"line_number":33,"context_line":"ROLE_ASSIGNMENT \u003d \u0027role_assignment\u0027"},{"line_number":34,"context_line":""},{"line_number":35,"context_line":""},{"line_number":36,"context_line":"class ArbitraryException(Exception):"}],"source_content_type":"text/x-python","patch_set":12,"id":"7ac7a964_9fbf18fb","line":33,"updated":"2014-08-16 07:18:48.000000000","message":"remove this line","commit_id":"749043e8aff79b4530edc3f916c3b6ac21edfb0f"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"7fb6beb30788a51636ee4f144788ae02ec2576cd","unresolved":false,"context_lines":[{"line_number":576,"context_line":"        self._assert_attachments(role_ref[\u0027id\u0027], self.project_id, self.user_id)"},{"line_number":577,"context_line":""},{"line_number":578,"context_line":"    def test_group_domain_grant(self):"},{"line_number":579,"context_line":"        role_ref \u003d self.new_role_ref()"},{"line_number":580,"context_line":"        self.assignment_api.create_role(role_ref[\u0027id\u0027], role_ref)"},{"line_number":581,"context_line":"        group_ref \u003d self.new_group_ref(domain_id\u003dself.domain_id)"},{"line_number":582,"context_line":"        group \u003d self.identity_api.create_group(group_ref)"}],"source_content_type":"text/x-python","patch_set":24,"id":"1abeadc6_29a1abf8","line":579,"updated":"2014-08-18 20:04:10.000000000","message":"there\u0027s a lot of duplicated code with these 2 new tests which should be put into a function to be shared.","commit_id":"75fd871b0e056b72be457c1e8f5bbf3838439258"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"6c158a55d196741d5ed8ce45bca2997a3321a228","unresolved":false,"context_lines":[{"line_number":576,"context_line":"        self._assert_attachments(role_ref[\u0027id\u0027], self.project_id, self.user_id)"},{"line_number":577,"context_line":""},{"line_number":578,"context_line":"    def test_group_domain_grant(self):"},{"line_number":579,"context_line":"        role_ref \u003d self.new_role_ref()"},{"line_number":580,"context_line":"        self.assignment_api.create_role(role_ref[\u0027id\u0027], role_ref)"},{"line_number":581,"context_line":"        group_ref \u003d self.new_group_ref(domain_id\u003dself.domain_id)"},{"line_number":582,"context_line":"        group \u003d self.identity_api.create_group(group_ref)"}],"source_content_type":"text/x-python","patch_set":24,"id":"1abeadc6_29328ba7","line":579,"in_reply_to":"1abeadc6_29a1abf8","updated":"2014-08-18 20:10:51.000000000","message":"i\u0027ll see what I can do","commit_id":"75fd871b0e056b72be457c1e8f5bbf3838439258"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"9d42b781220f0c44546032c315908dc0d8cf28ac","unresolved":false,"context_lines":[{"line_number":562,"context_line":"        self.post(\u0027/auth/tokens\u0027, body\u003ddata)"},{"line_number":563,"context_line":"        self._assertLastNotify(self.ACTION, user_id)"},{"line_number":564,"context_line":""},{"line_number":565,"context_line":"    def _test_role_assignment(self, url, role, target, actor):"},{"line_number":566,"context_line":"        self.put(url)"},{"line_number":567,"context_line":"        self._assertLastNotify(CREATED_OPERATION, self.user_id)"},{"line_number":568,"context_line":"        self._assert_attachments(role, target, actor)"}],"source_content_type":"text/x-python","patch_set":25,"id":"1abeadc6_726d4332","line":565,"updated":"2014-08-19 00:23:24.000000000","message":"Nice","commit_id":"5fb17fda3225c9c71f9b71649e4ca8381cde6537"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"ca6fdd3eaa95436d9404dc7f59c7bdcd388344a1","unresolved":false,"context_lines":[{"line_number":564,"context_line":""},{"line_number":565,"context_line":"    def _test_role_assignment(self, url, role, target, actor):"},{"line_number":566,"context_line":"        self.put(url)"},{"line_number":567,"context_line":"        self._assertLastNotify(CREATED_OPERATION, self.user_id)"},{"line_number":568,"context_line":"        self._assert_attachments(role, target, actor)"},{"line_number":569,"context_line":"        self.delete(url)"},{"line_number":570,"context_line":"        self._assertLastNotify(DELETED_OPERATION, self.user_id)"}],"source_content_type":"text/x-python","patch_set":25,"id":"1abeadc6_cbb55432","line":567,"updated":"2014-08-19 22:46:26.000000000","message":"rewrite this use the new method name: assert_last_note","commit_id":"5fb17fda3225c9c71f9b71649e4ca8381cde6537"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"8be378518db3171683aa495e188dbc24beb8635b","unresolved":false,"context_lines":[{"line_number":672,"context_line":"        self.delete(url)"},{"line_number":673,"context_line":"        action \u003d \"%s.%s\" % (DELETED_OPERATION, self.ROLE_ASSIGNMENT)"},{"line_number":674,"context_line":"        self._assert_last_note(action, self.user_id)"},{"line_number":675,"context_line":"        self._assert_event(role, project, domain, user, group)"},{"line_number":676,"context_line":""},{"line_number":677,"context_line":"    def test_user_project_grant(self):"},{"line_number":678,"context_line":"        url \u003d (\u0027/projects/%s/users/%s/roles/%s\u0027 %"}],"source_content_type":"text/x-python","patch_set":34,"id":"1abeadc6_d814cd4e","line":675,"updated":"2014-08-22 19:17:42.000000000","message":"Looks like there\u0027s no test for a failed assignment.","commit_id":"a5a17d984375cf9afb9a5f01493db8da23d5e531"}]}
