)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":15054,"name":"wangxiyuan","email":"wangxiyuan1007@gmail.com","username":"wangxiyuan"},"change_message_id":"a1e31b61f72e20ac8cf3cc836981da99880b1ada","unresolved":false,"context_lines":[{"line_number":9,"context_line":"Currently, a keystone IdP does not provide the"},{"line_number":10,"context_line":"groups to which user belong when generating SAML"},{"line_number":11,"context_line":"assertions.This patch adds an additional attribute"},{"line_number":12,"context_line":"called \"openstack_user_groups\" in the assertion."},{"line_number":13,"context_line":""},{"line_number":14,"context_line":"Change-Id: I205e8bbf9a4579b16177f57e29e363f4205a2b48"},{"line_number":15,"context_line":"Closes-Bug: #1641625"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":7,"id":"3f79a3b5_bbc2b9e8","line":12,"range":{"start_line":12,"start_character":8,"end_line":12,"end_character":29},"updated":"2018-08-06 10:21:20.000000000","message":"Oh, you use openstack_user_group without s in code. I think  openstack_user_groups is better.","commit_id":"c4e8f804e50c439249a21b538f1b900d8ecbd83b"},{"author":{"_account_id":27621,"name":"Vishakha Agarwal","email":"agarwalvishakha18@gmail.com","username":"Vishakha"},"change_message_id":"c9744506288185ea5932510c9d6ebfba834c1606","unresolved":false,"context_lines":[{"line_number":9,"context_line":"Currently, a keystone IdP does not provide the"},{"line_number":10,"context_line":"groups to which user belong when generating SAML"},{"line_number":11,"context_line":"assertions.This patch adds an additional attribute"},{"line_number":12,"context_line":"called \"openstack_user_groups\" in the assertion."},{"line_number":13,"context_line":""},{"line_number":14,"context_line":"Change-Id: I205e8bbf9a4579b16177f57e29e363f4205a2b48"},{"line_number":15,"context_line":"Closes-Bug: #1641625"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":7,"id":"3f79a3b5_ed32b8a7","line":12,"range":{"start_line":12,"start_character":8,"end_line":12,"end_character":29},"in_reply_to":"3f79a3b5_bbc2b9e8","updated":"2018-08-06 10:31:26.000000000","message":"done","commit_id":"c4e8f804e50c439249a21b538f1b900d8ecbd83b"}],"doc/source/admin/federation/mapping_combinations.rst":[{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"60a3e44c74fdc8a6e54655a8e455be645fef1509","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":38,"id":"3fa7e38b_2c9da96b","line":939,"updated":"2020-01-21 23:04:17.000000000","message":"Since this new mapping can\u0027t be used in the same way as the regular local \"group\" rule, it would be good to include an example of it.","commit_id":"6b21f9d1ca28589c39805b79f6404b02eea1f635"},{"author":{"_account_id":27621,"name":"Vishakha Agarwal","email":"agarwalvishakha18@gmail.com","username":"Vishakha"},"change_message_id":"38d61c3e7ce429f741fdf043b9bea66c93251213","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":38,"id":"3fa7e38b_d700e337","line":939,"in_reply_to":"3fa7e38b_2c9da96b","updated":"2020-01-27 07:26:04.000000000","message":"Done","commit_id":"6b21f9d1ca28589c39805b79f6404b02eea1f635"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"0143d860dcdd100d44bade53ba946880b085b9f1","unresolved":false,"context_lines":[{"line_number":933,"context_line":"       ]"},{"line_number":934,"context_line":"   }"},{"line_number":935,"context_line":""},{"line_number":936,"context_line":".. code-block:: xml"},{"line_number":937,"context_line":""},{"line_number":938,"context_line":"    \u003c!-- example 2 from a K2k Shibboleth implementation --\u003e"},{"line_number":939,"context_line":"    \u003cAttribute name\u003d\"openstack_user\" id\u003d\"openstack_user\"/\u003e"}],"source_content_type":"text/x-rst","patch_set":40,"id":"3fa7e38b_f165cbb0","line":936,"updated":"2020-01-28 23:33:55.000000000","message":"This could use more of an introduction before dropping straight into another code sample. Suggestion:\n\nA keystone user\u0027s groups can also be mapped to groups in the service provider. For example, with the following attributes declared in Shibboleth\u0027s attributes file: [xml snippet] then the following mapping can be used to map the user\u0027s group membership from the keystone IdP to groups in the keystone SP: [json snippet].","commit_id":"6d7bdac2aecd653ff9068c36f5809bad2bd13745"},{"author":{"_account_id":27621,"name":"Vishakha Agarwal","email":"agarwalvishakha18@gmail.com","username":"Vishakha"},"change_message_id":"200ffbdec517d6cf663c7973264320556c5b3de8","unresolved":false,"context_lines":[{"line_number":933,"context_line":"       ]"},{"line_number":934,"context_line":"   }"},{"line_number":935,"context_line":""},{"line_number":936,"context_line":".. code-block:: xml"},{"line_number":937,"context_line":""},{"line_number":938,"context_line":"    \u003c!-- example 2 from a K2k Shibboleth implementation --\u003e"},{"line_number":939,"context_line":"    \u003cAttribute name\u003d\"openstack_user\" id\u003d\"openstack_user\"/\u003e"}],"source_content_type":"text/x-rst","patch_set":40,"id":"3fa7e38b_203793e6","line":936,"in_reply_to":"3fa7e38b_f165cbb0","updated":"2020-02-14 10:34:57.000000000","message":"Done","commit_id":"6d7bdac2aecd653ff9068c36f5809bad2bd13745"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"0143d860dcdd100d44bade53ba946880b085b9f1","unresolved":false,"context_lines":[{"line_number":941,"context_line":""},{"line_number":942,"context_line":"``openstack_user``, and ``openstack_groups`` will be matched by service"},{"line_number":943,"context_line":"provider to the attribute names we have in the Identity Provider. It will"},{"line_number":944,"context_line":"map any user with the name matching to the ``openstack_user``. The identity"},{"line_number":945,"context_line":"provider will set the value of ``openstack_groups`` attribute in the form"},{"line_number":946,"context_line":"e.g \"JSON:{\u0027name\u0027:\u0027group1\u0027,\u0027domain\u0027:{\u0027name\u0027:\u0027Default\u0027}}\" which will be handled by"},{"line_number":947,"context_line":"service provider . This string will contain information about the user\u0027s groups and"}],"source_content_type":"text/x-rst","patch_set":40,"id":"3fa7e38b_910a57cd","line":944,"range":{"start_line":944,"start_character":22,"end_line":944,"end_character":61},"updated":"2020-01-28 23:33:55.000000000","message":"This does not make any sense. There is no matching - it just take the openstack_user attribute it finds in the assertion and inserts it directly in the mapping.","commit_id":"6d7bdac2aecd653ff9068c36f5809bad2bd13745"},{"author":{"_account_id":27621,"name":"Vishakha Agarwal","email":"agarwalvishakha18@gmail.com","username":"Vishakha"},"change_message_id":"200ffbdec517d6cf663c7973264320556c5b3de8","unresolved":false,"context_lines":[{"line_number":941,"context_line":""},{"line_number":942,"context_line":"``openstack_user``, and ``openstack_groups`` will be matched by service"},{"line_number":943,"context_line":"provider to the attribute names we have in the Identity Provider. It will"},{"line_number":944,"context_line":"map any user with the name matching to the ``openstack_user``. The identity"},{"line_number":945,"context_line":"provider will set the value of ``openstack_groups`` attribute in the form"},{"line_number":946,"context_line":"e.g \"JSON:{\u0027name\u0027:\u0027group1\u0027,\u0027domain\u0027:{\u0027name\u0027:\u0027Default\u0027}}\" which will be handled by"},{"line_number":947,"context_line":"service provider . This string will contain information about the user\u0027s groups and"}],"source_content_type":"text/x-rst","patch_set":40,"id":"3fa7e38b_4032cff4","line":944,"range":{"start_line":944,"start_character":22,"end_line":944,"end_character":61},"in_reply_to":"3fa7e38b_910a57cd","updated":"2020-02-14 10:34:57.000000000","message":"Done","commit_id":"6d7bdac2aecd653ff9068c36f5809bad2bd13745"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"0143d860dcdd100d44bade53ba946880b085b9f1","unresolved":false,"context_lines":[{"line_number":943,"context_line":"provider to the attribute names we have in the Identity Provider. It will"},{"line_number":944,"context_line":"map any user with the name matching to the ``openstack_user``. The identity"},{"line_number":945,"context_line":"provider will set the value of ``openstack_groups`` attribute in the form"},{"line_number":946,"context_line":"e.g \"JSON:{\u0027name\u0027:\u0027group1\u0027,\u0027domain\u0027:{\u0027name\u0027:\u0027Default\u0027}}\" which will be handled by"},{"line_number":947,"context_line":"service provider . This string will contain information about the user\u0027s groups and"},{"line_number":948,"context_line":"domain. SP will map group name to \"group1\" and its domain name to \"Default\" in"},{"line_number":949,"context_line":"``openstack_groups`` attribute."}],"source_content_type":"text/x-rst","patch_set":40,"id":"3fa7e38b_f1faabb8","line":946,"range":{"start_line":946,"start_character":0,"end_line":946,"end_character":57},"updated":"2020-01-28 23:33:55.000000000","message":"The JSON: string is an implementation detail of how the assertion will look, it is not important to the operator and shouldn\u0027t be mentioned here. Better to make it more abstract and just say that a user belonging to \u0027group1\u0027 in domain \u0027Default\u0027 in the IdP will map to a group with the same name and same domain\u0027s name in the SP.","commit_id":"6d7bdac2aecd653ff9068c36f5809bad2bd13745"},{"author":{"_account_id":27621,"name":"Vishakha Agarwal","email":"agarwalvishakha18@gmail.com","username":"Vishakha"},"change_message_id":"200ffbdec517d6cf663c7973264320556c5b3de8","unresolved":false,"context_lines":[{"line_number":943,"context_line":"provider to the attribute names we have in the Identity Provider. It will"},{"line_number":944,"context_line":"map any user with the name matching to the ``openstack_user``. The identity"},{"line_number":945,"context_line":"provider will set the value of ``openstack_groups`` attribute in the form"},{"line_number":946,"context_line":"e.g \"JSON:{\u0027name\u0027:\u0027group1\u0027,\u0027domain\u0027:{\u0027name\u0027:\u0027Default\u0027}}\" which will be handled by"},{"line_number":947,"context_line":"service provider . This string will contain information about the user\u0027s groups and"},{"line_number":948,"context_line":"domain. SP will map group name to \"group1\" and its domain name to \"Default\" in"},{"line_number":949,"context_line":"``openstack_groups`` attribute."}],"source_content_type":"text/x-rst","patch_set":40,"id":"3fa7e38b_e02c1b95","line":946,"range":{"start_line":946,"start_character":0,"end_line":946,"end_character":57},"in_reply_to":"3fa7e38b_f1faabb8","updated":"2020-02-14 10:34:57.000000000","message":"Done","commit_id":"6d7bdac2aecd653ff9068c36f5809bad2bd13745"}],"doc/source/advanced-topics/federation/mapping_combinations.rst":[{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"04b4fdc2d9e5c8a87b931a75e01cb7f8be5b11c2","unresolved":false,"context_lines":[{"line_number":937,"context_line":""},{"line_number":938,"context_line":"The possible attributes that can be used in a mapping are `openstack_user`,"},{"line_number":939,"context_line":"`openstack_user_domain`, `openstack_roles`, `openstack_project`,"},{"line_number":940,"context_line":"`openstack_project_domain` and `openstack_user_groups`."}],"source_content_type":"text/x-rst","patch_set":8,"id":"3f79a3b5_f8bca2bc","line":940,"range":{"start_line":940,"start_character":32,"end_line":940,"end_character":53},"updated":"2018-08-07 07:30:53.000000000","message":"I\u0027d prefer we call this just openstack_groups to be consistent with openstack_roles and openstack_project.","commit_id":"dc0867114f0b63ae525b46b66285d53c8a9dffc3"},{"author":{"_account_id":27621,"name":"Vishakha Agarwal","email":"agarwalvishakha18@gmail.com","username":"Vishakha"},"change_message_id":"653c5ce1c71fc8ba3868cdb2862c2df1a8de3fc0","unresolved":false,"context_lines":[{"line_number":937,"context_line":""},{"line_number":938,"context_line":"The possible attributes that can be used in a mapping are `openstack_user`,"},{"line_number":939,"context_line":"`openstack_user_domain`, `openstack_roles`, `openstack_project`,"},{"line_number":940,"context_line":"`openstack_project_domain` and `openstack_user_groups`."}],"source_content_type":"text/x-rst","patch_set":8,"id":"3f79a3b5_89ae822c","line":940,"range":{"start_line":940,"start_character":32,"end_line":940,"end_character":53},"in_reply_to":"3f79a3b5_f8bca2bc","updated":"2018-08-07 09:46:04.000000000","message":"As the groups are specific to user. So isn\u0027t it good to have openstack_user_groups like openstack_user_domain? Pl suggest","commit_id":"dc0867114f0b63ae525b46b66285d53c8a9dffc3"}],"keystone/api/_shared/saml.py":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"70928f7c820f670226ddfeeac44ca5d1dfe29211","unresolved":false,"context_lines":[{"line_number":46,"context_line":"    # between projects and users with the same name in different domains."},{"line_number":47,"context_line":"    project_domain_name \u003d token.project_domain[\u0027name\u0027]"},{"line_number":48,"context_line":"    subject_domain_name \u003d token.user_domain[\u0027name\u0027]"},{"line_number":49,"context_line":"    groups \u003d token.user_group_ids"},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"    generator \u003d keystone_idp.SAMLGenerator()"},{"line_number":52,"context_line":"    response \u003d generator.samlize_token("}],"source_content_type":"text/x-python","patch_set":11,"id":"3f79a3b5_76046c6c","line":49,"updated":"2018-11-27 19:38:45.000000000","message":"We have everything we need here to generate group membership:\n\n   groups \u003d PROVIDERS.identity_api.list_groups_for_user(\n                    token.user_id)\n   samlized_groups \u003d _samlize_groups(groups)\n\nor we can just have samlize_token handle a list of group IDs.\n\nWe can implement a method that actually is explicit about converting groups from the OpenStack format to SAML, as opposed to putting it in the token model.","commit_id":"ef69fcc91a7d90c000fcca26b63126df27a8e7e4"},{"author":{"_account_id":15054,"name":"wangxiyuan","email":"wangxiyuan1007@gmail.com","username":"wangxiyuan"},"change_message_id":"5ac182802914e1e356d58bf7060c8e01fbf401cc","unresolved":false,"context_lines":[{"line_number":60,"context_line":"            token.user_id)"},{"line_number":61,"context_line":"        for group in groups:"},{"line_number":62,"context_line":"            user_groups \u003d {}"},{"line_number":63,"context_line":"            user_group \u003d PROVIDERS.identity_api.get_group(group)"},{"line_number":64,"context_line":"            group_domain_name \u003d PROVIDERS.resource_api.get_domain("},{"line_number":65,"context_line":"                user_group[\u0027domain_id\u0027])[\u0027name\u0027]"},{"line_number":66,"context_line":"            user_groups[\u0027group_name\u0027] \u003d user_group[\u0027name\u0027]"}],"source_content_type":"text/x-python","patch_set":14,"id":"1f769fc5_a4d5b9bb","line":63,"range":{"start_line":63,"start_character":58,"end_line":63,"end_character":63},"updated":"2018-12-26 08:48:16.000000000","message":"I suppose the group already contains domain_id and name, why get it again here?","commit_id":"63e1c7f98ce82c83c02619543c5b14a9b643bcf9"},{"author":{"_account_id":15054,"name":"wangxiyuan","email":"wangxiyuan1007@gmail.com","username":"wangxiyuan"},"change_message_id":"1828f36791ed684bd2a87a9fea86080c65c1edeb","unresolved":false,"context_lines":[{"line_number":60,"context_line":"            token.user_id)"},{"line_number":61,"context_line":"        for group in groups:"},{"line_number":62,"context_line":"            user_groups \u003d {}"},{"line_number":63,"context_line":"            user_group \u003d PROVIDERS.identity_api.get_group(group)"},{"line_number":64,"context_line":"            group_domain_name \u003d PROVIDERS.resource_api.get_domain("},{"line_number":65,"context_line":"                user_group[\u0027domain_id\u0027])[\u0027name\u0027]"},{"line_number":66,"context_line":"            user_groups[\u0027group_name\u0027] \u003d user_group[\u0027name\u0027]"}],"source_content_type":"text/x-python","patch_set":14,"id":"1f769fc5_374f94be","line":63,"range":{"start_line":63,"start_character":58,"end_line":63,"end_character":63},"in_reply_to":"1f769fc5_177e18e4","updated":"2018-12-27 07:03:44.000000000","message":"\"user_group\" is the same as \"group\" I think. If you remove L63, the code still works\n\nit should be like:\n\ngroup_name \u003d group[\u0027name\u0027]\ngroup_domain_name \u003d PROVIDERS.resource_api.get_domain(group[\u0027domain_id\u0027])[\u0027name\u0027]","commit_id":"63e1c7f98ce82c83c02619543c5b14a9b643bcf9"},{"author":{"_account_id":27621,"name":"Vishakha Agarwal","email":"agarwalvishakha18@gmail.com","username":"Vishakha"},"change_message_id":"48dcd514ad720c147c17d081ec10b84fe7527f31","unresolved":false,"context_lines":[{"line_number":60,"context_line":"            token.user_id)"},{"line_number":61,"context_line":"        for group in groups:"},{"line_number":62,"context_line":"            user_groups \u003d {}"},{"line_number":63,"context_line":"            user_group \u003d PROVIDERS.identity_api.get_group(group)"},{"line_number":64,"context_line":"            group_domain_name \u003d PROVIDERS.resource_api.get_domain("},{"line_number":65,"context_line":"                user_group[\u0027domain_id\u0027])[\u0027name\u0027]"},{"line_number":66,"context_line":"            user_groups[\u0027group_name\u0027] \u003d user_group[\u0027name\u0027]"}],"source_content_type":"text/x-python","patch_set":14,"id":"1f769fc5_177e18e4","line":63,"range":{"start_line":63,"start_character":58,"end_line":63,"end_character":63},"in_reply_to":"1f769fc5_a4d5b9bb","updated":"2018-12-27 06:53:16.000000000","message":"Because group does not contain domain_name. As discussed in  mailing list [1], group will contain group_name and domain_name.\n\n[1] http://lists.openstack.org/pipermail/openstack-dev/2018-September/135151.html","commit_id":"63e1c7f98ce82c83c02619543c5b14a9b643bcf9"},{"author":{"_account_id":15054,"name":"wangxiyuan","email":"wangxiyuan1007@gmail.com","username":"wangxiyuan"},"change_message_id":"5ac182802914e1e356d58bf7060c8e01fbf401cc","unresolved":false,"context_lines":[{"line_number":65,"context_line":"                user_group[\u0027domain_id\u0027])[\u0027name\u0027]"},{"line_number":66,"context_line":"            user_groups[\u0027group_name\u0027] \u003d user_group[\u0027name\u0027]"},{"line_number":67,"context_line":"            user_groups[\u0027domain_name\u0027] \u003d group_domain_name"},{"line_number":68,"context_line":"            group_names.append(\u0027JSON:\u0027 + str(user_groups))"},{"line_number":69,"context_line":"        return group_names"},{"line_number":70,"context_line":"    groups \u003d group_membership()"},{"line_number":71,"context_line":"    generator \u003d keystone_idp.SAMLGenerator()"}],"source_content_type":"text/x-python","patch_set":14,"id":"1f769fc5_ce05747c","line":68,"range":{"start_line":68,"start_character":41,"end_line":68,"end_character":57},"updated":"2018-12-26 08:48:16.000000000","message":"use json.dumps instead.","commit_id":"63e1c7f98ce82c83c02619543c5b14a9b643bcf9"},{"author":{"_account_id":27621,"name":"Vishakha Agarwal","email":"agarwalvishakha18@gmail.com","username":"Vishakha"},"change_message_id":"48dcd514ad720c147c17d081ec10b84fe7527f31","unresolved":false,"context_lines":[{"line_number":65,"context_line":"                user_group[\u0027domain_id\u0027])[\u0027name\u0027]"},{"line_number":66,"context_line":"            user_groups[\u0027group_name\u0027] \u003d user_group[\u0027name\u0027]"},{"line_number":67,"context_line":"            user_groups[\u0027domain_name\u0027] \u003d group_domain_name"},{"line_number":68,"context_line":"            group_names.append(\u0027JSON:\u0027 + str(user_groups))"},{"line_number":69,"context_line":"        return group_names"},{"line_number":70,"context_line":"    groups \u003d group_membership()"},{"line_number":71,"context_line":"    generator \u003d keystone_idp.SAMLGenerator()"}],"source_content_type":"text/x-python","patch_set":14,"id":"1f769fc5_b782c4c7","line":68,"range":{"start_line":68,"start_character":41,"end_line":68,"end_character":57},"in_reply_to":"1f769fc5_ce05747c","updated":"2018-12-27 06:53:16.000000000","message":"done","commit_id":"63e1c7f98ce82c83c02619543c5b14a9b643bcf9"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"0076a3a5428378510090ce82297059c60537d1ab","unresolved":false,"context_lines":[{"line_number":10,"context_line":"#    License for the specific language governing permissions and limitations"},{"line_number":11,"context_line":"#    under the License."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"import json"},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"from keystone.common import provider_api"},{"line_number":16,"context_line":"import keystone.conf"}],"source_content_type":"text/x-python","patch_set":17,"id":"dfd5e7cf_99624d16","line":13,"range":{"start_line":13,"start_character":7,"end_line":13,"end_character":11},"updated":"2019-01-07 15:42:00.000000000","message":"We typically use jsonutils from oslo.serialization for things like this.\n\n  from oslo_serialization import jsonutils","commit_id":"32fd95cd58d35d6d72bca8f0b233e5cdcdc76053"},{"author":{"_account_id":27621,"name":"Vishakha Agarwal","email":"agarwalvishakha18@gmail.com","username":"Vishakha"},"change_message_id":"f8518ef1fe63660dda9cc946c699d1f4e83bc189","unresolved":false,"context_lines":[{"line_number":10,"context_line":"#    License for the specific language governing permissions and limitations"},{"line_number":11,"context_line":"#    under the License."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"import json"},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"from keystone.common import provider_api"},{"line_number":16,"context_line":"import keystone.conf"}],"source_content_type":"text/x-python","patch_set":17,"id":"dfd5e7cf_2048abca","line":13,"range":{"start_line":13,"start_character":7,"end_line":13,"end_character":11},"in_reply_to":"dfd5e7cf_99624d16","updated":"2019-01-08 16:12:51.000000000","message":"Done","commit_id":"32fd95cd58d35d6d72bca8f0b233e5cdcdc76053"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"0076a3a5428378510090ce82297059c60537d1ab","unresolved":false,"context_lines":[{"line_number":50,"context_line":"    subject_domain_name \u003d token.user_domain[\u0027name\u0027]"},{"line_number":51,"context_line":""},{"line_number":52,"context_line":"    def group_membership():"},{"line_number":53,"context_line":"        \"\"\":return dictionary with group_name and domain_name."},{"line_number":54,"context_line":""},{"line_number":55,"context_line":"        The expected return structure is::"},{"line_number":56,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"dfd5e7cf_d4b73c3a","line":53,"range":{"start_line":53,"start_character":19,"end_line":53,"end_character":29},"updated":"2019-01-07 15:42:00.000000000","message":"It looks like this method returns a list.","commit_id":"32fd95cd58d35d6d72bca8f0b233e5cdcdc76053"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"0076a3a5428378510090ce82297059c60537d1ab","unresolved":false,"context_lines":[{"line_number":50,"context_line":"    subject_domain_name \u003d token.user_domain[\u0027name\u0027]"},{"line_number":51,"context_line":""},{"line_number":52,"context_line":"    def group_membership():"},{"line_number":53,"context_line":"        \"\"\":return dictionary with group_name and domain_name."},{"line_number":54,"context_line":""},{"line_number":55,"context_line":"        The expected return structure is::"},{"line_number":56,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"dfd5e7cf_74f770f7","line":53,"range":{"start_line":53,"start_character":11,"end_line":53,"end_character":18},"updated":"2019-01-07 15:42:00.000000000","message":"This looks like docstring convention, but for returned variables. Nit: we could just say:\n\n  \"\"\"Returns a list of dictionaries serialized as strings.\"\"\"\n\nBut keeping the important format information you have at lines 55 - 58 in the comment, too.","commit_id":"32fd95cd58d35d6d72bca8f0b233e5cdcdc76053"},{"author":{"_account_id":27621,"name":"Vishakha Agarwal","email":"agarwalvishakha18@gmail.com","username":"Vishakha"},"change_message_id":"f8518ef1fe63660dda9cc946c699d1f4e83bc189","unresolved":false,"context_lines":[{"line_number":50,"context_line":"    subject_domain_name \u003d token.user_domain[\u0027name\u0027]"},{"line_number":51,"context_line":""},{"line_number":52,"context_line":"    def group_membership():"},{"line_number":53,"context_line":"        \"\"\":return dictionary with group_name and domain_name."},{"line_number":54,"context_line":""},{"line_number":55,"context_line":"        The expected return structure is::"},{"line_number":56,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"dfd5e7cf_0019e7d5","line":53,"range":{"start_line":53,"start_character":11,"end_line":53,"end_character":18},"in_reply_to":"dfd5e7cf_74f770f7","updated":"2019-01-08 16:12:51.000000000","message":"Done","commit_id":"32fd95cd58d35d6d72bca8f0b233e5cdcdc76053"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"0076a3a5428378510090ce82297059c60537d1ab","unresolved":false,"context_lines":[{"line_number":66,"context_line":"                group[\u0027domain_id\u0027])[\u0027name\u0027]"},{"line_number":67,"context_line":"            user_groups[\u0027group_name\u0027] \u003d group[\u0027name\u0027]"},{"line_number":68,"context_line":"            user_groups[\u0027domain_name\u0027] \u003d group_domain_name"},{"line_number":69,"context_line":"            group_names.append(\u0027JSON:\u0027 + json.dumps(user_groups))"},{"line_number":70,"context_line":"        return group_names"},{"line_number":71,"context_line":"    groups \u003d group_membership()"},{"line_number":72,"context_line":"    generator \u003d keystone_idp.SAMLGenerator()"}],"source_content_type":"text/x-python","patch_set":17,"id":"dfd5e7cf_397321ea","line":69,"range":{"start_line":69,"start_character":41,"end_line":69,"end_character":45},"updated":"2019-01-07 15:42:00.000000000","message":"Then here:\n\n  jsonutils.dumps(user_groups)\n\nI\u0027m not seeing anything real crazy with user_groups that would require us to use jsonutils (like nesting complex objects in the dictionary). Only making the comment for convention purposes.","commit_id":"32fd95cd58d35d6d72bca8f0b233e5cdcdc76053"},{"author":{"_account_id":27621,"name":"Vishakha Agarwal","email":"agarwalvishakha18@gmail.com","username":"Vishakha"},"change_message_id":"f8518ef1fe63660dda9cc946c699d1f4e83bc189","unresolved":false,"context_lines":[{"line_number":66,"context_line":"                group[\u0027domain_id\u0027])[\u0027name\u0027]"},{"line_number":67,"context_line":"            user_groups[\u0027group_name\u0027] \u003d group[\u0027name\u0027]"},{"line_number":68,"context_line":"            user_groups[\u0027domain_name\u0027] \u003d group_domain_name"},{"line_number":69,"context_line":"            group_names.append(\u0027JSON:\u0027 + json.dumps(user_groups))"},{"line_number":70,"context_line":"        return group_names"},{"line_number":71,"context_line":"    groups \u003d group_membership()"},{"line_number":72,"context_line":"    generator \u003d keystone_idp.SAMLGenerator()"}],"source_content_type":"text/x-python","patch_set":17,"id":"dfd5e7cf_8024f70e","line":69,"range":{"start_line":69,"start_character":41,"end_line":69,"end_character":45},"in_reply_to":"dfd5e7cf_397321ea","updated":"2019-01-08 16:12:51.000000000","message":"Done","commit_id":"32fd95cd58d35d6d72bca8f0b233e5cdcdc76053"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"3757b04c788b0aa3d3dbc3482ea5217cb1a0a27e","unresolved":false,"context_lines":[{"line_number":55,"context_line":"        The expected return structure is::"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":"        [JSON:{\"group_name\":\"group_1\",\"domain_name\": \"Default\","},{"line_number":58,"context_line":"        JSON:{\"group_name\":\"group_2\",\"domain_name\": \"Default\"}]"},{"line_number":59,"context_line":"        \"\"\""},{"line_number":60,"context_line":"        group_names \u003d []"},{"line_number":61,"context_line":"        groups \u003d PROVIDERS.identity_api.list_groups_for_user("}],"source_content_type":"text/x-python","patch_set":22,"id":"bfdaf3ff_41b155e1","line":58,"updated":"2019-01-11 11:17:29.000000000","message":"(nit) spacing is inconsistent","commit_id":"2e426052c755812a4522961659ad49494322839c"},{"author":{"_account_id":27621,"name":"Vishakha Agarwal","email":"agarwalvishakha18@gmail.com","username":"Vishakha"},"change_message_id":"3bc0afdff1d47d48e83a7fec2a151b9e3d6dda76","unresolved":false,"context_lines":[{"line_number":55,"context_line":"        The expected return structure is::"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":"        [JSON:{\"group_name\":\"group_1\",\"domain_name\": \"Default\","},{"line_number":58,"context_line":"        JSON:{\"group_name\":\"group_2\",\"domain_name\": \"Default\"}]"},{"line_number":59,"context_line":"        \"\"\""},{"line_number":60,"context_line":"        group_names \u003d []"},{"line_number":61,"context_line":"        groups \u003d PROVIDERS.identity_api.list_groups_for_user("}],"source_content_type":"text/x-python","patch_set":22,"id":"bfdaf3ff_6ddbd91a","line":58,"in_reply_to":"bfdaf3ff_41b155e1","updated":"2019-01-16 09:48:16.000000000","message":"Done","commit_id":"2e426052c755812a4522961659ad49494322839c"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"3757b04c788b0aa3d3dbc3482ea5217cb1a0a27e","unresolved":false,"context_lines":[{"line_number":61,"context_line":"        groups \u003d PROVIDERS.identity_api.list_groups_for_user("},{"line_number":62,"context_line":"            token.user_id)"},{"line_number":63,"context_line":"        for group in groups:"},{"line_number":64,"context_line":"            user_groups \u003d {}"},{"line_number":65,"context_line":"            group_domain_name \u003d PROVIDERS.resource_api.get_domain("},{"line_number":66,"context_line":"                group[\u0027domain_id\u0027])[\u0027name\u0027]"},{"line_number":67,"context_line":"            user_groups[\"group_name\"] \u003d group[\u0027name\u0027]"}],"source_content_type":"text/x-python","patch_set":22,"id":"bfdaf3ff_c1ab0573","line":64,"range":{"start_line":64,"start_character":12,"end_line":64,"end_character":23},"updated":"2019-01-11 11:17:29.000000000","message":"(nit) since this is only one group I would call it user_group","commit_id":"2e426052c755812a4522961659ad49494322839c"},{"author":{"_account_id":27621,"name":"Vishakha Agarwal","email":"agarwalvishakha18@gmail.com","username":"Vishakha"},"change_message_id":"3bc0afdff1d47d48e83a7fec2a151b9e3d6dda76","unresolved":false,"context_lines":[{"line_number":61,"context_line":"        groups \u003d PROVIDERS.identity_api.list_groups_for_user("},{"line_number":62,"context_line":"            token.user_id)"},{"line_number":63,"context_line":"        for group in groups:"},{"line_number":64,"context_line":"            user_groups \u003d {}"},{"line_number":65,"context_line":"            group_domain_name \u003d PROVIDERS.resource_api.get_domain("},{"line_number":66,"context_line":"                group[\u0027domain_id\u0027])[\u0027name\u0027]"},{"line_number":67,"context_line":"            user_groups[\"group_name\"] \u003d group[\u0027name\u0027]"}],"source_content_type":"text/x-python","patch_set":22,"id":"bfdaf3ff_8dd63df1","line":64,"range":{"start_line":64,"start_character":12,"end_line":64,"end_character":23},"in_reply_to":"bfdaf3ff_c1ab0573","updated":"2019-01-16 09:48:16.000000000","message":"Done","commit_id":"2e426052c755812a4522961659ad49494322839c"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"3757b04c788b0aa3d3dbc3482ea5217cb1a0a27e","unresolved":false,"context_lines":[{"line_number":66,"context_line":"                group[\u0027domain_id\u0027])[\u0027name\u0027]"},{"line_number":67,"context_line":"            user_groups[\"group_name\"] \u003d group[\u0027name\u0027]"},{"line_number":68,"context_line":"            user_groups[\"domain_name\"] \u003d group_domain_name"},{"line_number":69,"context_line":"            group_names.append(\u0027JSON:\u0027 + jsonutils.dumps(user_groups))"},{"line_number":70,"context_line":"        return jsonutils.dumps(group_names)"},{"line_number":71,"context_line":"    groups \u003d group_membership()"},{"line_number":72,"context_line":"    generator \u003d keystone_idp.SAMLGenerator()"}],"source_content_type":"text/x-python","patch_set":22,"id":"bfdaf3ff_a1bcc1bb","line":69,"range":{"start_line":69,"start_character":12,"end_line":69,"end_character":23},"updated":"2019-01-11 11:17:29.000000000","message":"(nit) since this isn\u0027t just names I would call it user_groups","commit_id":"2e426052c755812a4522961659ad49494322839c"},{"author":{"_account_id":27621,"name":"Vishakha Agarwal","email":"agarwalvishakha18@gmail.com","username":"Vishakha"},"change_message_id":"3bc0afdff1d47d48e83a7fec2a151b9e3d6dda76","unresolved":false,"context_lines":[{"line_number":66,"context_line":"                group[\u0027domain_id\u0027])[\u0027name\u0027]"},{"line_number":67,"context_line":"            user_groups[\"group_name\"] \u003d group[\u0027name\u0027]"},{"line_number":68,"context_line":"            user_groups[\"domain_name\"] \u003d group_domain_name"},{"line_number":69,"context_line":"            group_names.append(\u0027JSON:\u0027 + jsonutils.dumps(user_groups))"},{"line_number":70,"context_line":"        return jsonutils.dumps(group_names)"},{"line_number":71,"context_line":"    groups \u003d group_membership()"},{"line_number":72,"context_line":"    generator \u003d keystone_idp.SAMLGenerator()"}],"source_content_type":"text/x-python","patch_set":22,"id":"bfdaf3ff_4d0a958a","line":69,"range":{"start_line":69,"start_character":12,"end_line":69,"end_character":23},"in_reply_to":"bfdaf3ff_a1bcc1bb","updated":"2019-01-16 09:48:16.000000000","message":"Done","commit_id":"2e426052c755812a4522961659ad49494322839c"},{"author":{"_account_id":16465,"name":"Kristi Nikolla","email":"knikolla@bu.edu","username":"knikolla"},"change_message_id":"2482f4f152533c1d123297d29023498283219bb8","unresolved":false,"context_lines":[{"line_number":67,"context_line":"            user_group[\"name\"] \u003d group[\u0027name\u0027]"},{"line_number":68,"context_line":"            user_group[\"domain\"] \u003d {\u0027name\u0027: group_domain_name}"},{"line_number":69,"context_line":"            user_groups.append(\u0027JSON:\u0027 + jsonutils.dumps(user_group))"},{"line_number":70,"context_line":"        return \u0027;\u0027.join(user_groups)"},{"line_number":71,"context_line":"    groups \u003d group_membership()"},{"line_number":72,"context_line":"    generator \u003d keystone_idp.SAMLGenerator()"},{"line_number":73,"context_line":"    response \u003d generator.samlize_token("}],"source_content_type":"text/x-python","patch_set":46,"id":"1fa4df85_5572ef4a","line":70,"range":{"start_line":70,"start_character":8,"end_line":70,"end_character":36},"updated":"2020-03-03 15:28:10.000000000","message":"Why not return the list of dictionaries here, and have samlize token convert it into appropriate format.","commit_id":"748bfb2d74201a5203466d29cfd4e56d71796d2d"},{"author":{"_account_id":27621,"name":"Vishakha Agarwal","email":"agarwalvishakha18@gmail.com","username":"Vishakha"},"change_message_id":"fd430ce0b33b47631294b587042a2180c5af2e1c","unresolved":false,"context_lines":[{"line_number":67,"context_line":"            user_group[\"name\"] \u003d group[\u0027name\u0027]"},{"line_number":68,"context_line":"            user_group[\"domain\"] \u003d {\u0027name\u0027: group_domain_name}"},{"line_number":69,"context_line":"            user_groups.append(\u0027JSON:\u0027 + jsonutils.dumps(user_group))"},{"line_number":70,"context_line":"        return \u0027;\u0027.join(user_groups)"},{"line_number":71,"context_line":"    groups \u003d group_membership()"},{"line_number":72,"context_line":"    generator \u003d keystone_idp.SAMLGenerator()"},{"line_number":73,"context_line":"    response \u003d generator.samlize_token("}],"source_content_type":"text/x-python","patch_set":46,"id":"1fa4df85_2ea2784c","line":70,"range":{"start_line":70,"start_character":8,"end_line":70,"end_character":36},"in_reply_to":"1fa4df85_5572ef4a","updated":"2020-03-04 07:27:02.000000000","message":"Done","commit_id":"748bfb2d74201a5203466d29cfd4e56d71796d2d"}],"keystone/federation/idp.py":[{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"04b4fdc2d9e5c8a87b931a75e01cb7f8be5b11c2","unresolved":false,"context_lines":[{"line_number":200,"context_line":"                  \u003cns0:AttributeValue"},{"line_number":201,"context_line":"                  xsi:type\u003d\"xs:string\"\u003e153c4873464d48a488efbb6628fdba94"},{"line_number":202,"context_line":"                  \u003c/ns0:AttributeValue\u003e"},{"line_number":203,"context_line":"            \u003c/ns0:Attribute\u003e"},{"line_number":204,"context_line":""},{"line_number":205,"context_line":"        \u003c/ns0:AttributeStatement\u003e"},{"line_number":206,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"3f79a3b5_b36f2bc4","line":203,"updated":"2018-08-07 07:30:53.000000000","message":"All of the other attributes here use human readable names rather than IDs, so it would be nice if this was consistent with that. However I see why you chose IDs here, since there\u0027s not a good way to have a list of group names and also identify them by their domains...will have to think on it","commit_id":"dc0867114f0b63ae525b46b66285d53c8a9dffc3"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"7f836e86747cd9b6b3074c53c4aeb89ebfb7956d","unresolved":false,"context_lines":[{"line_number":200,"context_line":"                  \u003cns0:AttributeValue"},{"line_number":201,"context_line":"                  xsi:type\u003d\"xs:string\"\u003e153c4873464d48a488efbb6628fdba94"},{"line_number":202,"context_line":"                  \u003c/ns0:AttributeValue\u003e"},{"line_number":203,"context_line":"            \u003c/ns0:Attribute\u003e"},{"line_number":204,"context_line":""},{"line_number":205,"context_line":"        \u003c/ns0:AttributeStatement\u003e"},{"line_number":206,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"3f79a3b5_3365bf46","line":203,"in_reply_to":"3f79a3b5_b36f2bc4","updated":"2018-08-14 14:14:23.000000000","message":"I realized why it\u0027s not just inconsistent but actually invalid to use uuids instead of names here. Two keystones are not going to have groups with identical IDs, and it makes no sense to try to map a random uuid from one keystone to a sensible group in the second keystone.","commit_id":"dc0867114f0b63ae525b46b66285d53c8a9dffc3"},{"author":{"_account_id":15054,"name":"wangxiyuan","email":"wangxiyuan1007@gmail.com","username":"wangxiyuan"},"change_message_id":"5ac182802914e1e356d58bf7060c8e01fbf401cc","unresolved":false,"context_lines":[{"line_number":197,"context_line":"                \u003cns0:AttributeValue"},{"line_number":198,"context_line":"                   xsi:type\u003d\"xs:string\"\u003eJSON:{\"group_name\": \"admins\","},{"line_number":199,"context_line":"                   \"domain_name\": \"Default\"}"},{"line_number":200,"context_line":"                   \u003cns0:AttributeValue"},{"line_number":201,"context_line":"                   xsi:type\u003d\"xs:string\"\u003eJSON:{\"group_name\": \"nonadmins\","},{"line_number":202,"context_line":"                   \"domain_name\": \"Default\"}\u003c/ns0:AttributeValue\u003e"},{"line_number":203,"context_line":"            \u003c/ns0:Attribute\u003e"}],"source_content_type":"text/x-python","patch_set":14,"id":"1f769fc5_c478f5f9","line":200,"range":{"start_line":200,"start_character":16,"end_line":200,"end_character":19},"updated":"2018-12-26 08:48:16.000000000","message":"the level should be the same with L197","commit_id":"63e1c7f98ce82c83c02619543c5b14a9b643bcf9"},{"author":{"_account_id":27621,"name":"Vishakha Agarwal","email":"agarwalvishakha18@gmail.com","username":"Vishakha"},"change_message_id":"48dcd514ad720c147c17d081ec10b84fe7527f31","unresolved":false,"context_lines":[{"line_number":197,"context_line":"                \u003cns0:AttributeValue"},{"line_number":198,"context_line":"                   xsi:type\u003d\"xs:string\"\u003eJSON:{\"group_name\": \"admins\","},{"line_number":199,"context_line":"                   \"domain_name\": \"Default\"}"},{"line_number":200,"context_line":"                   \u003cns0:AttributeValue"},{"line_number":201,"context_line":"                   xsi:type\u003d\"xs:string\"\u003eJSON:{\"group_name\": \"nonadmins\","},{"line_number":202,"context_line":"                   \"domain_name\": \"Default\"}\u003c/ns0:AttributeValue\u003e"},{"line_number":203,"context_line":"            \u003c/ns0:Attribute\u003e"}],"source_content_type":"text/x-python","patch_set":14,"id":"1f769fc5_776c2c36","line":200,"range":{"start_line":200,"start_character":16,"end_line":200,"end_character":19},"in_reply_to":"1f769fc5_c478f5f9","updated":"2018-12-27 06:53:16.000000000","message":"done","commit_id":"63e1c7f98ce82c83c02619543c5b14a9b643bcf9"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"0076a3a5428378510090ce82297059c60537d1ab","unresolved":false,"context_lines":[{"line_number":66,"context_line":"        :type project: string"},{"line_number":67,"context_line":"        :param project_domain_name: Project Domain name"},{"line_number":68,"context_line":"        :type project_domain_name: string"},{"line_number":69,"context_line":"        :param groups: List of dict of user group and domain name"},{"line_number":70,"context_line":"        :type groups: list"},{"line_number":71,"context_line":"        :param expires_in: Sets how long the assertion is valid for, in seconds"},{"line_number":72,"context_line":"        :type expires_in: int"}],"source_content_type":"text/x-python","patch_set":17,"id":"dfd5e7cf_f469208b","line":69,"range":{"start_line":69,"start_character":31,"end_line":69,"end_character":35},"updated":"2019-01-07 15:42:00.000000000","message":"These are strings though. But we could explain here the strings are serialized dictionaries.","commit_id":"32fd95cd58d35d6d72bca8f0b233e5cdcdc76053"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"0076a3a5428378510090ce82297059c60537d1ab","unresolved":false,"context_lines":[{"line_number":66,"context_line":"        :type project: string"},{"line_number":67,"context_line":"        :param project_domain_name: Project Domain name"},{"line_number":68,"context_line":"        :type project_domain_name: string"},{"line_number":69,"context_line":"        :param groups: List of dict of user group and domain name"},{"line_number":70,"context_line":"        :type groups: list"},{"line_number":71,"context_line":"        :param expires_in: Sets how long the assertion is valid for, in seconds"},{"line_number":72,"context_line":"        :type expires_in: int"}],"source_content_type":"text/x-python","patch_set":17,"id":"dfd5e7cf_1412a459","line":69,"range":{"start_line":69,"start_character":44,"end_line":69,"end_character":49},"updated":"2019-01-07 15:42:00.000000000","message":"nit: groups*","commit_id":"32fd95cd58d35d6d72bca8f0b233e5cdcdc76053"},{"author":{"_account_id":27621,"name":"Vishakha Agarwal","email":"agarwalvishakha18@gmail.com","username":"Vishakha"},"change_message_id":"f8518ef1fe63660dda9cc946c699d1f4e83bc189","unresolved":false,"context_lines":[{"line_number":66,"context_line":"        :type project: string"},{"line_number":67,"context_line":"        :param project_domain_name: Project Domain name"},{"line_number":68,"context_line":"        :type project_domain_name: string"},{"line_number":69,"context_line":"        :param groups: List of dict of user group and domain name"},{"line_number":70,"context_line":"        :type groups: list"},{"line_number":71,"context_line":"        :param expires_in: Sets how long the assertion is valid for, in seconds"},{"line_number":72,"context_line":"        :type expires_in: int"}],"source_content_type":"text/x-python","patch_set":17,"id":"dfd5e7cf_a0b7bb86","line":69,"range":{"start_line":69,"start_character":31,"end_line":69,"end_character":35},"in_reply_to":"dfd5e7cf_f469208b","updated":"2019-01-08 16:12:51.000000000","message":"Done","commit_id":"32fd95cd58d35d6d72bca8f0b233e5cdcdc76053"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"869274318716438283f7fd0ee7c85b5337c745d8","unresolved":false,"context_lines":[{"line_number":212,"context_line":"            attribute \u003d saml.Attribute()"},{"line_number":213,"context_line":"            attribute.name \u003d attribute_name"},{"line_number":214,"context_line":""},{"line_number":215,"context_line":"            for value in attribute_values:"},{"line_number":216,"context_line":"                attribute_value \u003d saml.AttributeValue()"},{"line_number":217,"context_line":"                attribute_value.set_text(value)"},{"line_number":218,"context_line":"                attribute.attribute_value.append(attribute_value)"}],"source_content_type":"text/x-python","patch_set":32,"id":"9fdfeff1_02aeef2e","line":215,"updated":"2019-03-03 18:19:39.000000000","message":"This isn\u0027t working correctly, this generates an assertion with one character per attribute, like this: http://paste.openstack.org/show/747201/","commit_id":"1c4231ff4fa72a0ea1262c1543791231b2b22150"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"0f6ac2cf76f7c5b4795511a08135485bfbb5768b","unresolved":false,"context_lines":[{"line_number":227,"context_line":"        user_domain_attribute \u003d _build_attribute("},{"line_number":228,"context_line":"            \u0027openstack_user_domain\u0027, [user_domain_name])"},{"line_number":229,"context_line":"        groups_attribute \u003d _build_attribute("},{"line_number":230,"context_line":"            \u0027openstack_groups\u0027, groups.split(\u0027;\u0027))"},{"line_number":231,"context_line":""},{"line_number":232,"context_line":"        attribute_statement \u003d saml.AttributeStatement()"},{"line_number":233,"context_line":"        attribute_statement.attribute.append(user_attribute)"}],"source_content_type":"text/x-python","patch_set":36,"id":"3fa7e38b_252525c0","line":230,"updated":"2020-01-14 21:44:43.000000000","message":"The CI is failing because the signature is broken, I think because this doesn\u0027t build a valid attribute if groups is empty - \u0027\u0027.split(\u0027;\u0027) creates a list [\u0027\u0027] and the attribute becomes a single element list containing a null element. I think better not to add the list at all if there are no groups.\n\nFWIW besides looking at the apache and shibboleth logs I found that by inserting an rpdb break statement around here and checking groups_attribute.to_string() https://pypi.org/project/rpdb/","commit_id":"07c3a9e85bd3586887b85061721d631b31340a0e"},{"author":{"_account_id":16465,"name":"Kristi Nikolla","email":"knikolla@bu.edu","username":"knikolla"},"change_message_id":"2482f4f152533c1d123297d29023498283219bb8","unresolved":false,"context_lines":[{"line_number":238,"context_line":""},{"line_number":239,"context_line":"        if groups:"},{"line_number":240,"context_line":"            groups_attribute \u003d _build_attribute("},{"line_number":241,"context_line":"                \u0027openstack_groups\u0027, groups.split(\u0027;\u0027))"},{"line_number":242,"context_line":"            attribute_statement.attribute.append(groups_attribute)"},{"line_number":243,"context_line":""},{"line_number":244,"context_line":"        LOG.debug(\" attribute_statement is : %s\","}],"source_content_type":"text/x-python","patch_set":46,"id":"1fa4df85_757feb14","line":241,"range":{"start_line":241,"start_character":36,"end_line":241,"end_character":53},"updated":"2020-03-03 15:28:10.000000000","message":"This will not work, since \";\" is a valid character in a group name. Why do you not pass the actual list to the samlize_token function, instead of making it into a string and then splitting it back.","commit_id":"748bfb2d74201a5203466d29cfd4e56d71796d2d"},{"author":{"_account_id":27621,"name":"Vishakha Agarwal","email":"agarwalvishakha18@gmail.com","username":"Vishakha"},"change_message_id":"fd430ce0b33b47631294b587042a2180c5af2e1c","unresolved":false,"context_lines":[{"line_number":238,"context_line":""},{"line_number":239,"context_line":"        if groups:"},{"line_number":240,"context_line":"            groups_attribute \u003d _build_attribute("},{"line_number":241,"context_line":"                \u0027openstack_groups\u0027, groups.split(\u0027;\u0027))"},{"line_number":242,"context_line":"            attribute_statement.attribute.append(groups_attribute)"},{"line_number":243,"context_line":""},{"line_number":244,"context_line":"        LOG.debug(\" attribute_statement is : %s\","}],"source_content_type":"text/x-python","patch_set":46,"id":"1fa4df85_ee8780b4","line":241,"range":{"start_line":241,"start_character":36,"end_line":241,"end_character":53},"in_reply_to":"1fa4df85_757feb14","updated":"2020-03-04 07:27:02.000000000","message":"Done","commit_id":"748bfb2d74201a5203466d29cfd4e56d71796d2d"}],"keystone/federation/utils.py":[{"author":{"_account_id":15054,"name":"wangxiyuan","email":"wangxiyuan1007@gmail.com","username":"wangxiyuan"},"change_message_id":"5ac182802914e1e356d58bf7060c8e01fbf401cc","unresolved":false,"context_lines":[{"line_number":514,"context_line":"        LOG.debug(\u0027assertion data: %s\u0027, assertion_data)"},{"line_number":515,"context_line":"        if \"JSON\" in assertion_data:"},{"line_number":516,"context_line":"            # Handles the assertion_data containing JSON tag for groups."},{"line_number":517,"context_line":"            \u0027\u0027.join(assertion_data.split(\"JSON:\"))"},{"line_number":518,"context_line":"        assertion \u003d {n: v.split(\u0027;\u0027) for n, v in assertion_data.items()"},{"line_number":519,"context_line":"                     if isinstance(v, six.string_types)}"},{"line_number":520,"context_line":"        LOG.debug(\u0027assertion: %s\u0027, assertion)"}],"source_content_type":"text/x-python","patch_set":14,"id":"1f769fc5_648561ad","line":517,"range":{"start_line":517,"start_character":20,"end_line":517,"end_character":34},"updated":"2018-12-26 08:48:16.000000000","message":"assertion_data is a dict, it can\u0027t be split obviously. So the related unittest should be added as well.","commit_id":"63e1c7f98ce82c83c02619543c5b14a9b643bcf9"},{"author":{"_account_id":27621,"name":"Vishakha Agarwal","email":"agarwalvishakha18@gmail.com","username":"Vishakha"},"change_message_id":"48dcd514ad720c147c17d081ec10b84fe7527f31","unresolved":false,"context_lines":[{"line_number":514,"context_line":"        LOG.debug(\u0027assertion data: %s\u0027, assertion_data)"},{"line_number":515,"context_line":"        if \"JSON\" in assertion_data:"},{"line_number":516,"context_line":"            # Handles the assertion_data containing JSON tag for groups."},{"line_number":517,"context_line":"            \u0027\u0027.join(assertion_data.split(\"JSON:\"))"},{"line_number":518,"context_line":"        assertion \u003d {n: v.split(\u0027;\u0027) for n, v in assertion_data.items()"},{"line_number":519,"context_line":"                     if isinstance(v, six.string_types)}"},{"line_number":520,"context_line":"        LOG.debug(\u0027assertion: %s\u0027, assertion)"}],"source_content_type":"text/x-python","patch_set":14,"id":"1f769fc5_3776b408","line":517,"range":{"start_line":517,"start_character":20,"end_line":517,"end_character":34},"in_reply_to":"1f769fc5_648561ad","updated":"2018-12-27 06:53:16.000000000","message":"done. Working over test case","commit_id":"63e1c7f98ce82c83c02619543c5b14a9b643bcf9"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"0076a3a5428378510090ce82297059c60537d1ab","unresolved":false,"context_lines":[{"line_number":515,"context_line":"        LOG.debug(\u0027assertion data: %s\u0027, assertion_data)"},{"line_number":516,"context_line":"        for key, value in assertion_data.items():"},{"line_number":517,"context_line":"            if isinstance(value, six.string_types) and \u0027JSON\u0027 in value:"},{"line_number":518,"context_line":"                assertion_data[key] \u003d json.loads(\u0027\u0027.join(value.split(\"JSON:\")))"},{"line_number":519,"context_line":"        assertion \u003d {n: v.split(\u0027;\u0027) for n, v in assertion_data.items()"},{"line_number":520,"context_line":"                     if isinstance(v, six.string_types)}"},{"line_number":521,"context_line":"        LOG.debug(\u0027assertion: %s\u0027, assertion)"}],"source_content_type":"text/x-python","patch_set":17,"id":"dfd5e7cf_343808d2","line":518,"range":{"start_line":518,"start_character":38,"end_line":518,"end_character":42},"updated":"2019-01-07 15:42:00.000000000","message":"Same comment here as in the previous module.","commit_id":"32fd95cd58d35d6d72bca8f0b233e5cdcdc76053"},{"author":{"_account_id":27621,"name":"Vishakha Agarwal","email":"agarwalvishakha18@gmail.com","username":"Vishakha"},"change_message_id":"f8518ef1fe63660dda9cc946c699d1f4e83bc189","unresolved":false,"context_lines":[{"line_number":515,"context_line":"        LOG.debug(\u0027assertion data: %s\u0027, assertion_data)"},{"line_number":516,"context_line":"        for key, value in assertion_data.items():"},{"line_number":517,"context_line":"            if isinstance(value, six.string_types) and \u0027JSON\u0027 in value:"},{"line_number":518,"context_line":"                assertion_data[key] \u003d json.loads(\u0027\u0027.join(value.split(\"JSON:\")))"},{"line_number":519,"context_line":"        assertion \u003d {n: v.split(\u0027;\u0027) for n, v in assertion_data.items()"},{"line_number":520,"context_line":"                     if isinstance(v, six.string_types)}"},{"line_number":521,"context_line":"        LOG.debug(\u0027assertion: %s\u0027, assertion)"}],"source_content_type":"text/x-python","patch_set":17,"id":"dfd5e7cf_c0bc3f6b","line":518,"range":{"start_line":518,"start_character":38,"end_line":518,"end_character":42},"in_reply_to":"dfd5e7cf_343808d2","updated":"2019-01-08 16:12:51.000000000","message":"Done","commit_id":"32fd95cd58d35d6d72bca8f0b233e5cdcdc76053"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"3757b04c788b0aa3d3dbc3482ea5217cb1a0a27e","unresolved":false,"context_lines":[{"line_number":514,"context_line":"        # any multiple values are stored in the arrays."},{"line_number":515,"context_line":"        LOG.debug(\u0027assertion data: %s\u0027, assertion_data)"},{"line_number":516,"context_line":"        for key, value in assertion_data.items():"},{"line_number":517,"context_line":"            if isinstance(value, six.string_types) and \u0027JSON\u0027 in value:"},{"line_number":518,"context_line":"                assertion_data[key] \u003d jsonutils.loads(\u0027\u0027.join(value.split(\"JSON:\")))"},{"line_number":519,"context_line":"        assertion \u003d {n: v.split(\u0027;\u0027) for n, v in assertion_data.items()"},{"line_number":520,"context_line":"                     if isinstance(v, six.string_types)}"}],"source_content_type":"text/x-python","patch_set":22,"id":"bfdaf3ff_41aab585","line":517,"range":{"start_line":517,"start_character":55,"end_line":517,"end_character":70},"updated":"2019-01-11 11:17:29.000000000","message":"I would use value.startswith(\u0027JSON:\u0027), otherwise if the string had JSON in it for any other reason this would match. -1 for this since it\u0027s slightly dangerous not to be precise here.","commit_id":"2e426052c755812a4522961659ad49494322839c"},{"author":{"_account_id":27621,"name":"Vishakha Agarwal","email":"agarwalvishakha18@gmail.com","username":"Vishakha"},"change_message_id":"3bc0afdff1d47d48e83a7fec2a151b9e3d6dda76","unresolved":false,"context_lines":[{"line_number":514,"context_line":"        # any multiple values are stored in the arrays."},{"line_number":515,"context_line":"        LOG.debug(\u0027assertion data: %s\u0027, assertion_data)"},{"line_number":516,"context_line":"        for key, value in assertion_data.items():"},{"line_number":517,"context_line":"            if isinstance(value, six.string_types) and \u0027JSON\u0027 in value:"},{"line_number":518,"context_line":"                assertion_data[key] \u003d jsonutils.loads(\u0027\u0027.join(value.split(\"JSON:\")))"},{"line_number":519,"context_line":"        assertion \u003d {n: v.split(\u0027;\u0027) for n, v in assertion_data.items()"},{"line_number":520,"context_line":"                     if isinstance(v, six.string_types)}"}],"source_content_type":"text/x-python","patch_set":22,"id":"bfdaf3ff_8def1daf","line":517,"range":{"start_line":517,"start_character":55,"end_line":517,"end_character":70},"in_reply_to":"bfdaf3ff_41aab585","updated":"2019-01-16 09:48:16.000000000","message":"Done","commit_id":"2e426052c755812a4522961659ad49494322839c"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"3757b04c788b0aa3d3dbc3482ea5217cb1a0a27e","unresolved":false,"context_lines":[{"line_number":515,"context_line":"        LOG.debug(\u0027assertion data: %s\u0027, assertion_data)"},{"line_number":516,"context_line":"        for key, value in assertion_data.items():"},{"line_number":517,"context_line":"            if isinstance(value, six.string_types) and \u0027JSON\u0027 in value:"},{"line_number":518,"context_line":"                assertion_data[key] \u003d jsonutils.loads(\u0027\u0027.join(value.split(\"JSON:\")))"},{"line_number":519,"context_line":"        assertion \u003d {n: v.split(\u0027;\u0027) for n, v in assertion_data.items()"},{"line_number":520,"context_line":"                     if isinstance(v, six.string_types)}"},{"line_number":521,"context_line":"        LOG.debug(\u0027assertion: %s\u0027, assertion)"}],"source_content_type":"text/x-python","patch_set":22,"id":"bfdaf3ff_217a1124","line":518,"range":{"start_line":518,"start_character":54,"end_line":518,"end_character":82},"updated":"2019-01-11 11:17:29.000000000","message":"more of a nitpick but I would use value.lstrip(\u0027JSON:\u0027) here instead of splitting and joining","commit_id":"2e426052c755812a4522961659ad49494322839c"},{"author":{"_account_id":27621,"name":"Vishakha Agarwal","email":"agarwalvishakha18@gmail.com","username":"Vishakha"},"change_message_id":"3bc0afdff1d47d48e83a7fec2a151b9e3d6dda76","unresolved":false,"context_lines":[{"line_number":515,"context_line":"        LOG.debug(\u0027assertion data: %s\u0027, assertion_data)"},{"line_number":516,"context_line":"        for key, value in assertion_data.items():"},{"line_number":517,"context_line":"            if isinstance(value, six.string_types) and \u0027JSON\u0027 in value:"},{"line_number":518,"context_line":"                assertion_data[key] \u003d jsonutils.loads(\u0027\u0027.join(value.split(\"JSON:\")))"},{"line_number":519,"context_line":"        assertion \u003d {n: v.split(\u0027;\u0027) for n, v in assertion_data.items()"},{"line_number":520,"context_line":"                     if isinstance(v, six.string_types)}"},{"line_number":521,"context_line":"        LOG.debug(\u0027assertion: %s\u0027, assertion)"}],"source_content_type":"text/x-python","patch_set":22,"id":"bfdaf3ff_2d2cf100","line":518,"range":{"start_line":518,"start_character":54,"end_line":518,"end_character":82},"in_reply_to":"bfdaf3ff_217a1124","updated":"2019-01-16 09:48:16.000000000","message":"Changed the following part. Done","commit_id":"2e426052c755812a4522961659ad49494322839c"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"5dd6a043c0ee9170fe436d36a2f7ad7476bdfd22","unresolved":false,"context_lines":[{"line_number":515,"context_line":"        LOG.debug(\u0027assertion data: %s\u0027, assertion_data)"},{"line_number":516,"context_line":"        for key, value in assertion_data.items():"},{"line_number":517,"context_line":"            if isinstance(value, six.string_types) and value[2:].startswith(\u0027JSON\u0027):"},{"line_number":518,"context_line":"                assertion_data[key] \u003d jsonutils.dumps(jsonutils.loads(value).get(\u0027JSON\u0027, None))"},{"line_number":519,"context_line":""},{"line_number":520,"context_line":"        assertion \u003d {n: v.split(\u0027;\u0027) for n, v in assertion_data.items()"},{"line_number":521,"context_line":"                     if isinstance(v, six.string_types)}"}],"source_content_type":"text/x-python","patch_set":29,"id":"9fdfeff1_48975f49","line":518,"range":{"start_line":518,"start_character":38,"end_line":518,"end_character":53},"updated":"2019-02-01 13:00:03.000000000","message":".dumps is just reversing the .loads and so the value remains a string, why not keep it as an object?","commit_id":"3bce19eea5c3930692e771bc8dceb1e2fa6a6acd"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"5dd6a043c0ee9170fe436d36a2f7ad7476bdfd22","unresolved":false,"context_lines":[{"line_number":515,"context_line":"        LOG.debug(\u0027assertion data: %s\u0027, assertion_data)"},{"line_number":516,"context_line":"        for key, value in assertion_data.items():"},{"line_number":517,"context_line":"            if isinstance(value, six.string_types) and value[2:].startswith(\u0027JSON\u0027):"},{"line_number":518,"context_line":"                assertion_data[key] \u003d jsonutils.dumps(jsonutils.loads(value).get(\u0027JSON\u0027, None))"},{"line_number":519,"context_line":""},{"line_number":520,"context_line":"        assertion \u003d {n: v.split(\u0027;\u0027) for n, v in assertion_data.items()"},{"line_number":521,"context_line":"                     if isinstance(v, six.string_types)}"}],"source_content_type":"text/x-python","patch_set":29,"id":"9fdfeff1_a8accb9e","line":518,"range":{"start_line":518,"start_character":77,"end_line":518,"end_character":94},"updated":"2019-02-01 13:00:03.000000000","message":".get looks for a key called \u0027JSON\u0027 in the dictionary, but there should not be a key called JSON, that should have been stripped before trying to load the string as a JSON object","commit_id":"3bce19eea5c3930692e771bc8dceb1e2fa6a6acd"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"5dd6a043c0ee9170fe436d36a2f7ad7476bdfd22","unresolved":false,"context_lines":[{"line_number":515,"context_line":"        LOG.debug(\u0027assertion data: %s\u0027, assertion_data)"},{"line_number":516,"context_line":"        for key, value in assertion_data.items():"},{"line_number":517,"context_line":"            if isinstance(value, six.string_types) and value[2:].startswith(\u0027JSON\u0027):"},{"line_number":518,"context_line":"                assertion_data[key] \u003d jsonutils.dumps(jsonutils.loads(value).get(\u0027JSON\u0027, None))"},{"line_number":519,"context_line":""},{"line_number":520,"context_line":"        assertion \u003d {n: v.split(\u0027;\u0027) for n, v in assertion_data.items()"},{"line_number":521,"context_line":"                     if isinstance(v, six.string_types)}"}],"source_content_type":"text/x-python","patch_set":29,"id":"9fdfeff1_e8a653c1","line":518,"range":{"start_line":518,"start_character":64,"end_line":518,"end_character":76},"updated":"2019-02-01 13:00:03.000000000","message":"does this .loads call work? The JSON: prefix hasn\u0027t been stripped yet","commit_id":"3bce19eea5c3930692e771bc8dceb1e2fa6a6acd"},{"author":{"_account_id":27621,"name":"Vishakha Agarwal","email":"agarwalvishakha18@gmail.com","username":"Vishakha"},"change_message_id":"9e4540869257da89b1997ef0f5f9e4d329987445","unresolved":false,"context_lines":[{"line_number":701,"context_line":"            remote match from a local section of a rule"},{"line_number":702,"context_line":""},{"line_number":703,"context_line":"        \"\"\""},{"line_number":704,"context_line":"        LOG.debug(\u0027direct_maps: %s\u0027, direct_maps)"},{"line_number":705,"context_line":"        LOG.debug(\u0027local: %s\u0027, local)"},{"line_number":706,"context_line":"        new \u003d {}"},{"line_number":707,"context_line":"        for k, v in local.items():"}],"source_content_type":"text/x-python","patch_set":30,"id":"9fdfeff1_6d1d500e","line":704,"updated":"2019-02-06 11:05:07.000000000","message":"My direct_maps contains - \n\n[[\u0027bwilliams\u0027], [\u0027[{\"group_name\": \"group_1\", \"domain_name\": \"default\"}, {\"group_name\": \"group_2\", \"domain_name\": \"default\"}]\u0027]]","commit_id":"575cfd946284e173ecdbf7628fef550c7dd5316c"},{"author":{"_account_id":27621,"name":"Vishakha Agarwal","email":"agarwalvishakha18@gmail.com","username":"Vishakha"},"change_message_id":"9e4540869257da89b1997ef0f5f9e4d329987445","unresolved":false,"context_lines":[{"line_number":712,"context_line":"                             for item in v]"},{"line_number":713,"context_line":"            else:"},{"line_number":714,"context_line":"                try:"},{"line_number":715,"context_line":"                    new_value \u003d v.format(*direct_maps)"},{"line_number":716,"context_line":"                except IndexError:"},{"line_number":717,"context_line":"                    raise exception.DirectMappingError("},{"line_number":718,"context_line":"                        mapping_id\u003dself.mapping_id)"}],"source_content_type":"text/x-python","patch_set":30,"id":"9fdfeff1_2d1748f0","line":715,"range":{"start_line":715,"start_character":32,"end_line":715,"end_character":53},"updated":"2019-02-06 11:05:07.000000000","message":"Not getting mapped here. May be a syntax issue??","commit_id":"575cfd946284e173ecdbf7628fef550c7dd5316c"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"86511cc2c9e030ca6e0faae242d1d6aaadc0b9a4","unresolved":false,"context_lines":[{"line_number":556,"context_line":"        LOG.debug(\u0027mapped_properties: %s\u0027, mapped_properties)"},{"line_number":557,"context_line":"        return mapped_properties"},{"line_number":558,"context_line":""},{"line_number":559,"context_line":"    @staticmethod"},{"line_number":560,"context_line":"    def _normalize_groups(identity_value):"},{"line_number":561,"context_line":"        # In this case, identity_value[\u0027groups\u0027] is a string"},{"line_number":562,"context_line":"        # representation of a list, and we want a real list.  This is"}],"source_content_type":"text/x-python","patch_set":49,"id":"1fa4df85_b8a9fcdd","line":559,"updated":"2020-03-18 21:31:11.000000000","message":"why is this a static method? it doesn\u0027t look like it needs to be?","commit_id":"2e2780a7fcd3d73de44fcc0da660c86547c90a3d"},{"author":{"_account_id":27621,"name":"Vishakha Agarwal","email":"agarwalvishakha18@gmail.com","username":"Vishakha"},"change_message_id":"a3cbfd2e411f0c6382c81f07bcd895b573353f32","unresolved":false,"context_lines":[{"line_number":556,"context_line":"        LOG.debug(\u0027mapped_properties: %s\u0027, mapped_properties)"},{"line_number":557,"context_line":"        return mapped_properties"},{"line_number":558,"context_line":""},{"line_number":559,"context_line":"    @staticmethod"},{"line_number":560,"context_line":"    def _normalize_groups(identity_value):"},{"line_number":561,"context_line":"        # In this case, identity_value[\u0027groups\u0027] is a string"},{"line_number":562,"context_line":"        # representation of a list, and we want a real list.  This is"}],"source_content_type":"text/x-python","patch_set":49,"id":"1fa4df85_99950b35","line":559,"in_reply_to":"1fa4df85_b8a9fcdd","updated":"2020-03-19 12:05:14.000000000","message":"Nice Catch.","commit_id":"2e2780a7fcd3d73de44fcc0da660c86547c90a3d"}],"keystone/models/token_model.py":[{"author":{"_account_id":15054,"name":"wangxiyuan","email":"wangxiyuan1007@gmail.com","username":"wangxiyuan"},"change_message_id":"a7a4d870ede854adeadc12c9222aa6da4ac753d2","unresolved":false,"context_lines":[{"line_number":250,"context_line":"                )"},{"line_number":251,"context_line":"        return self.__trust_project_domain"},{"line_number":252,"context_line":""},{"line_number":253,"context_line":"    @property"},{"line_number":254,"context_line":"    def get_user_group_ids(self):"},{"line_number":255,"context_line":"        user_group_ids \u003d []"},{"line_number":256,"context_line":"        groups \u003d PROVIDERS.identity_api.list_groups_for_user(self.user_id)"},{"line_number":257,"context_line":"        for user_group_id in groups:"},{"line_number":258,"context_line":"            user_group_ids.append(user_group_id[\u0027id\u0027])"},{"line_number":259,"context_line":"        return user_group_ids"},{"line_number":260,"context_line":""},{"line_number":261,"context_line":"    def _get_system_roles(self):"},{"line_number":262,"context_line":"        roles \u003d []"}],"source_content_type":"text/x-python","patch_set":2,"id":"5f7c97a3_1d3965cf","line":259,"range":{"start_line":253,"start_character":0,"end_line":259,"end_character":29},"updated":"2018-08-03 07:22:29.000000000","message":"this property should be rewrite like other properties do, such as:\nthe name should be \"def user_group_ids\".\nyou should make sure self.user_id is not null before get its groups and so on.","commit_id":"28e890369beb90e407ad6fdcf655900014c391ac"},{"author":{"_account_id":27621,"name":"Vishakha Agarwal","email":"agarwalvishakha18@gmail.com","username":"Vishakha"},"change_message_id":"df8616627443017dd6ac8362c32ba087b3fd70eb","unresolved":false,"context_lines":[{"line_number":250,"context_line":"                )"},{"line_number":251,"context_line":"        return self.__trust_project_domain"},{"line_number":252,"context_line":""},{"line_number":253,"context_line":"    @property"},{"line_number":254,"context_line":"    def get_user_group_ids(self):"},{"line_number":255,"context_line":"        user_group_ids \u003d []"},{"line_number":256,"context_line":"        groups \u003d PROVIDERS.identity_api.list_groups_for_user(self.user_id)"},{"line_number":257,"context_line":"        for user_group_id in groups:"},{"line_number":258,"context_line":"            user_group_ids.append(user_group_id[\u0027id\u0027])"},{"line_number":259,"context_line":"        return user_group_ids"},{"line_number":260,"context_line":""},{"line_number":261,"context_line":"    def _get_system_roles(self):"},{"line_number":262,"context_line":"        roles \u003d []"}],"source_content_type":"text/x-python","patch_set":2,"id":"5f7c97a3_2cdc3070","line":259,"range":{"start_line":253,"start_character":0,"end_line":259,"end_character":29},"in_reply_to":"5f7c97a3_1d3965cf","updated":"2018-08-03 09:31:07.000000000","message":"Done","commit_id":"28e890369beb90e407ad6fdcf655900014c391ac"},{"author":{"_account_id":15054,"name":"wangxiyuan","email":"wangxiyuan1007@gmail.com","username":"wangxiyuan"},"change_message_id":"160f0143858c73aaa18cbe631faac7731abc74c8","unresolved":false,"context_lines":[{"line_number":251,"context_line":"        return self.__trust_project_domain"},{"line_number":252,"context_line":""},{"line_number":253,"context_line":"    @property"},{"line_number":254,"context_line":"    def user_group_ids(self):"},{"line_number":255,"context_line":"        user_group_ids \u003d []"},{"line_number":256,"context_line":"        if self.user_id is not None:"},{"line_number":257,"context_line":"            groups \u003d PROVIDERS.identity_api.list_groups_for_user(self.user_id)"}],"source_content_type":"text/x-python","patch_set":4,"id":"3f79a3b5_cc0905de","line":254,"updated":"2018-08-06 02:42:47.000000000","message":"add a self.__user_group_ids property so that we only need to call \"list_groups_for_user\" once.","commit_id":"0ca72eb9877c4869f317de6e609368a2dba40bea"},{"author":{"_account_id":15054,"name":"wangxiyuan","email":"wangxiyuan1007@gmail.com","username":"wangxiyuan"},"change_message_id":"9f7e20f07951ca173ed1da1c1099b07bcbe8850e","unresolved":false,"context_lines":[{"line_number":249,"context_line":"                )"},{"line_number":250,"context_line":"        return self.__trust_project_domain"},{"line_number":251,"context_line":""},{"line_number":252,"context_line":"    @property"},{"line_number":253,"context_line":"    def user_group_ids(self):"},{"line_number":254,"context_line":"        # list groups for user"},{"line_number":255,"context_line":"        if not self.__user_group_ids:"}],"source_content_type":"text/x-python","patch_set":11,"id":"3f79a3b5_f9d76120","line":252,"updated":"2018-11-22 03:54:17.000000000","message":"this kind of format \"JSON:xxxx\" is just used for federation saml content. So I don\u0027t think we should add it in the token model.","commit_id":"ef69fcc91a7d90c000fcca26b63126df27a8e7e4"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"70e863aa44777273d16a1ddb929abea5c1d4fc2d","unresolved":false,"context_lines":[{"line_number":249,"context_line":"                )"},{"line_number":250,"context_line":"        return self.__trust_project_domain"},{"line_number":251,"context_line":""},{"line_number":252,"context_line":"    @property"},{"line_number":253,"context_line":"    def user_group_ids(self):"},{"line_number":254,"context_line":"        # list groups for user"},{"line_number":255,"context_line":"        if not self.__user_group_ids:"}],"source_content_type":"text/x-python","patch_set":11,"id":"3f79a3b5_df5ad71d","line":252,"in_reply_to":"3f79a3b5_76dd4c10","updated":"2018-12-03 08:54:56.000000000","message":"Agreed","commit_id":"ef69fcc91a7d90c000fcca26b63126df27a8e7e4"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"70928f7c820f670226ddfeeac44ca5d1dfe29211","unresolved":false,"context_lines":[{"line_number":249,"context_line":"                )"},{"line_number":250,"context_line":"        return self.__trust_project_domain"},{"line_number":251,"context_line":""},{"line_number":252,"context_line":"    @property"},{"line_number":253,"context_line":"    def user_group_ids(self):"},{"line_number":254,"context_line":"        # list groups for user"},{"line_number":255,"context_line":"        if not self.__user_group_ids:"}],"source_content_type":"text/x-python","patch_set":11,"id":"3f79a3b5_76dd4c10","line":252,"in_reply_to":"3f79a3b5_f9d76120","updated":"2018-11-27 19:38:45.000000000","message":"++\n\nAs far as I can tell, groups are only included in token responses if keystone is dealing with a federated token, and we special case that when we render the token.\n\nSince user groups aren\u0027t really a formal attribute of tokens, we could omit this and build group membership where we need it in the federated identity provider code.\n\n[0] https://git.openstack.org/cgit/openstack/keystone/tree/keystone/common/render_token.py#n116","commit_id":"ef69fcc91a7d90c000fcca26b63126df27a8e7e4"}],"keystone/tests/unit/contrib/federation/test_utils.py":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"15c43c9d14e4c9a1fc778e1ab0a3f1f89a6f4bff","unresolved":false,"context_lines":[{"line_number":14,"context_line":"import uuid"},{"line_number":15,"context_line":""},{"line_number":16,"context_line":"from oslo_config import fixture as config_fixture"},{"line_number":17,"context_line":"``"},{"line_number":18,"context_line":""},{"line_number":19,"context_line":"from keystone.auth.plugins import mapped"},{"line_number":20,"context_line":"import keystone.conf"}],"source_content_type":"text/x-python","patch_set":18,"id":"dfd5e7cf_24f8bae3","line":17,"range":{"start_line":17,"start_character":0,"end_line":17,"end_character":2},"updated":"2019-01-08 19:04:16.000000000","message":"We\u0027ll need to remove this and re-add the import. Doing [0] locally got everything passing for me.\n\n[0] https://pasted.tech/pastes/b24efe3bd9920e9c243006086ca372345ede6900.raw","commit_id":"4db761db87943cf913bfa41e107a7a17dc658190"},{"author":{"_account_id":27621,"name":"Vishakha Agarwal","email":"agarwalvishakha18@gmail.com","username":"Vishakha"},"change_message_id":"6bf4f2341d7e529581e0b487f6e1556c37723a8f","unresolved":false,"context_lines":[{"line_number":14,"context_line":"import uuid"},{"line_number":15,"context_line":""},{"line_number":16,"context_line":"from oslo_config import fixture as config_fixture"},{"line_number":17,"context_line":"``"},{"line_number":18,"context_line":""},{"line_number":19,"context_line":"from keystone.auth.plugins import mapped"},{"line_number":20,"context_line":"import keystone.conf"}],"source_content_type":"text/x-python","patch_set":18,"id":"dfd5e7cf_5dc58c3b","line":17,"range":{"start_line":17,"start_character":0,"end_line":17,"end_character":2},"in_reply_to":"dfd5e7cf_24f8bae3","updated":"2019-01-09 03:58:52.000000000","message":"Don\u0027t know how this happened.","commit_id":"4db761db87943cf913bfa41e107a7a17dc658190"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"1b3b544e5cca4ce641f13a3dae655aeaeb4a7f84","unresolved":false,"context_lines":[{"line_number":528,"context_line":"            domain_id\u003dmapping_fixtures.LOCAL_DOMAIN)"},{"line_number":529,"context_line":""},{"line_number":530,"context_line":"    def test_user_identifications_name(self):"},{"line_number":531,"context_line":"        \"\"\"Test various mapping options and how users are identified."},{"line_number":532,"context_line":""},{"line_number":533,"context_line":"        This test calls mapped.setup_username() for propagating user object."},{"line_number":534,"context_line":""}],"source_content_type":"text/x-python","patch_set":21,"id":"dfd5e7cf_d765c746","line":531,"range":{"start_line":531,"start_character":16,"end_line":531,"end_character":23},"updated":"2019-01-09 20:26:58.000000000","message":"unrelated changes?","commit_id":"5caec760a4f7b4ba5ab96b30bbcc746e50eb65c0"},{"author":{"_account_id":27621,"name":"Vishakha Agarwal","email":"agarwalvishakha18@gmail.com","username":"Vishakha"},"change_message_id":"7fa6a40c9855606cc9d68e7935c9a10394b2bf7a","unresolved":false,"context_lines":[{"line_number":528,"context_line":"            domain_id\u003dmapping_fixtures.LOCAL_DOMAIN)"},{"line_number":529,"context_line":""},{"line_number":530,"context_line":"    def test_user_identifications_name(self):"},{"line_number":531,"context_line":"        \"\"\"Test various mapping options and how users are identified."},{"line_number":532,"context_line":""},{"line_number":533,"context_line":"        This test calls mapped.setup_username() for propagating user object."},{"line_number":534,"context_line":""}],"source_content_type":"text/x-python","patch_set":21,"id":"bfdaf3ff_eddba27a","line":531,"range":{"start_line":531,"start_character":16,"end_line":531,"end_character":23},"in_reply_to":"dfd5e7cf_48e123d0","updated":"2019-01-11 06:49:44.000000000","message":"Thanks Lance for the suggestion. Updated a separate patch for it.\nhttps://review.openstack.org/#/c/630036/","commit_id":"5caec760a4f7b4ba5ab96b30bbcc746e50eb65c0"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"aaa31ab4fe9f87055dbbe81fd1bad7c696266a9e","unresolved":false,"context_lines":[{"line_number":528,"context_line":"            domain_id\u003dmapping_fixtures.LOCAL_DOMAIN)"},{"line_number":529,"context_line":""},{"line_number":530,"context_line":"    def test_user_identifications_name(self):"},{"line_number":531,"context_line":"        \"\"\"Test various mapping options and how users are identified."},{"line_number":532,"context_line":""},{"line_number":533,"context_line":"        This test calls mapped.setup_username() for propagating user object."},{"line_number":534,"context_line":""}],"source_content_type":"text/x-python","patch_set":21,"id":"dfd5e7cf_48e123d0","line":531,"range":{"start_line":531,"start_character":16,"end_line":531,"end_character":23},"in_reply_to":"dfd5e7cf_662ea6fb","updated":"2019-01-10 17:15:05.000000000","message":"We could pull this out into a separate change. Just so we keep changes isolated to only the things required for that change, bug fix, or feature.\n\nThis would be an easy patch to approve separately.","commit_id":"5caec760a4f7b4ba5ab96b30bbcc746e50eb65c0"},{"author":{"_account_id":27621,"name":"Vishakha Agarwal","email":"agarwalvishakha18@gmail.com","username":"Vishakha"},"change_message_id":"125e80539b03ac350d1466d9e0211881094b2e58","unresolved":false,"context_lines":[{"line_number":528,"context_line":"            domain_id\u003dmapping_fixtures.LOCAL_DOMAIN)"},{"line_number":529,"context_line":""},{"line_number":530,"context_line":"    def test_user_identifications_name(self):"},{"line_number":531,"context_line":"        \"\"\"Test various mapping options and how users are identified."},{"line_number":532,"context_line":""},{"line_number":533,"context_line":"        This test calls mapped.setup_username() for propagating user object."},{"line_number":534,"context_line":""}],"source_content_type":"text/x-python","patch_set":21,"id":"dfd5e7cf_662ea6fb","line":531,"range":{"start_line":531,"start_character":16,"end_line":531,"end_character":23},"in_reply_to":"dfd5e7cf_d765c746","updated":"2019-01-10 05:03:49.000000000","message":"yes. Thought to fix the incorrect spelling.","commit_id":"5caec760a4f7b4ba5ab96b30bbcc746e50eb65c0"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"3757b04c788b0aa3d3dbc3482ea5217cb1a0a27e","unresolved":false,"context_lines":[{"line_number":177,"context_line":"        self.assertValidMappedUserObject(values)"},{"line_number":178,"context_line":"        user_name \u003d assertion.get(\u0027UserName\u0027)"},{"line_number":179,"context_line":"        user_groups \u003d jsonutils.loads(assertion.get(\u0027Groups\u0027))"},{"line_number":180,"context_line":"        if user_groups:"},{"line_number":181,"context_line":"            user_group \u003d user_groups[0][\u0027group_name\u0027]"},{"line_number":182,"context_line":"            user_domain \u003d user_groups[0][\u0027domain_name\u0027]"},{"line_number":183,"context_line":"        groups \u003d jsonutils.loads(values.get(\u0027user\u0027, {}).get(\u0027groups\u0027))"},{"line_number":184,"context_line":"        if groups:"},{"line_number":185,"context_line":"            group_name \u003d groups[0][\u0027group_name\u0027]"},{"line_number":186,"context_line":"            domain_name \u003d groups[0][\u0027domain_name\u0027]"},{"line_number":187,"context_line":"        group_ids \u003d values.get(\u0027group_ids\u0027)"},{"line_number":188,"context_line":"        name \u003d values.get(\u0027user\u0027, {}).get(\u0027name\u0027)"},{"line_number":189,"context_line":""}],"source_content_type":"text/x-python","patch_set":22,"id":"bfdaf3ff_812adde4","line":186,"range":{"start_line":180,"start_character":8,"end_line":186,"end_character":50},"updated":"2019-01-11 11:17:29.000000000","message":"This test case is confusing to me, why would there not be user groups for this test fixture?","commit_id":"2e426052c755812a4522961659ad49494322839c"},{"author":{"_account_id":27621,"name":"Vishakha Agarwal","email":"agarwalvishakha18@gmail.com","username":"Vishakha"},"change_message_id":"3bc0afdff1d47d48e83a7fec2a151b9e3d6dda76","unresolved":false,"context_lines":[{"line_number":177,"context_line":"        self.assertValidMappedUserObject(values)"},{"line_number":178,"context_line":"        user_name \u003d assertion.get(\u0027UserName\u0027)"},{"line_number":179,"context_line":"        user_groups \u003d jsonutils.loads(assertion.get(\u0027Groups\u0027))"},{"line_number":180,"context_line":"        if user_groups:"},{"line_number":181,"context_line":"            user_group \u003d user_groups[0][\u0027group_name\u0027]"},{"line_number":182,"context_line":"            user_domain \u003d user_groups[0][\u0027domain_name\u0027]"},{"line_number":183,"context_line":"        groups \u003d jsonutils.loads(values.get(\u0027user\u0027, {}).get(\u0027groups\u0027))"},{"line_number":184,"context_line":"        if groups:"},{"line_number":185,"context_line":"            group_name \u003d groups[0][\u0027group_name\u0027]"},{"line_number":186,"context_line":"            domain_name \u003d groups[0][\u0027domain_name\u0027]"},{"line_number":187,"context_line":"        group_ids \u003d values.get(\u0027group_ids\u0027)"},{"line_number":188,"context_line":"        name \u003d values.get(\u0027user\u0027, {}).get(\u0027name\u0027)"},{"line_number":189,"context_line":""}],"source_content_type":"text/x-python","patch_set":22,"id":"bfdaf3ff_cd3a0533","line":186,"range":{"start_line":180,"start_character":8,"end_line":186,"end_character":50},"in_reply_to":"bfdaf3ff_812adde4","updated":"2019-01-16 09:48:16.000000000","message":"Makes Sense. There will always be user groups for this test case. Removed the if condition","commit_id":"2e426052c755812a4522961659ad49494322839c"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"86511cc2c9e030ca6e0faae242d1d6aaadc0b9a4","unresolved":false,"context_lines":[{"line_number":160,"context_line":"        self.assertEqual(user_name, name)"},{"line_number":161,"context_line":"        self.assertEqual([], group_ids,)"},{"line_number":162,"context_line":""},{"line_number":163,"context_line":"    def test_rule_engine_for_groups_and_domain(self):"},{"line_number":164,"context_line":"        \"\"\"Should return user\u0027s groups and group domain."},{"line_number":165,"context_line":""},{"line_number":166,"context_line":"        The GROUP_DOMAIN_ASSERTION should successfully have a match in"}],"source_content_type":"text/x-python","patch_set":49,"id":"1fa4df85_98976091","line":163,"updated":"2020-03-18 21:31:11.000000000","message":"(nit) it\u0027s slightly odd to add this test here because it\u0027s in between two tests that are testing the not_any_of function of the mapping engine, and this test isn\u0027t about that. would make more sense either at the end of this class or near other tests that are about groups.","commit_id":"2e2780a7fcd3d73de44fcc0da660c86547c90a3d"},{"author":{"_account_id":27621,"name":"Vishakha Agarwal","email":"agarwalvishakha18@gmail.com","username":"Vishakha"},"change_message_id":"a3cbfd2e411f0c6382c81f07bcd895b573353f32","unresolved":false,"context_lines":[{"line_number":160,"context_line":"        self.assertEqual(user_name, name)"},{"line_number":161,"context_line":"        self.assertEqual([], group_ids,)"},{"line_number":162,"context_line":""},{"line_number":163,"context_line":"    def test_rule_engine_for_groups_and_domain(self):"},{"line_number":164,"context_line":"        \"\"\"Should return user\u0027s groups and group domain."},{"line_number":165,"context_line":""},{"line_number":166,"context_line":"        The GROUP_DOMAIN_ASSERTION should successfully have a match in"}],"source_content_type":"text/x-python","patch_set":49,"id":"1fa4df85_f9bd1fb7","line":163,"in_reply_to":"1fa4df85_98976091","updated":"2020-03-19 12:05:14.000000000","message":"Done","commit_id":"2e2780a7fcd3d73de44fcc0da660c86547c90a3d"}],"keystone/tests/unit/mapping_fixtures.py":[{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"3757b04c788b0aa3d3dbc3482ea5217cb1a0a27e","unresolved":false,"context_lines":[{"line_number":1640,"context_line":"    \u0027orgPersonType\u0027: \u0027Customer\u0027,"},{"line_number":1641,"context_line":"    \u0027Groups\u0027: jsonutils.dumps(\u0027[JSON:{\"group_name\":\"group_1\", \"domain_name\": \"default\"}, \u0027"},{"line_number":1642,"context_line":"                              \u0027JSON:{\"group_name\": \"group_2\", \"domain_name\": \"default\"}]\u0027)"},{"line_number":1643,"context_line":"}"},{"line_number":1644,"context_line":""},{"line_number":1645,"context_line":"MAPPING_UNICODE \u003d {"},{"line_number":1646,"context_line":"    \"rules\": ["}],"source_content_type":"text/x-python","patch_set":22,"id":"bfdaf3ff_a1cb611c","line":1643,"updated":"2019-01-11 11:17:29.000000000","message":"This bug is about including groups in the assertion coming from a keystone IdP, not about interpreting groups from an arbitrary IdP, so instead of this I would add a test case that looks more like the assertion that will be coming from the keystone IdP, e.g. with openstack_user and openstack_groups etc.","commit_id":"2e426052c755812a4522961659ad49494322839c"},{"author":{"_account_id":27621,"name":"Vishakha Agarwal","email":"agarwalvishakha18@gmail.com","username":"Vishakha"},"change_message_id":"3bc0afdff1d47d48e83a7fec2a151b9e3d6dda76","unresolved":false,"context_lines":[{"line_number":1640,"context_line":"    \u0027orgPersonType\u0027: \u0027Customer\u0027,"},{"line_number":1641,"context_line":"    \u0027Groups\u0027: jsonutils.dumps(\u0027[JSON:{\"group_name\":\"group_1\", \"domain_name\": \"default\"}, \u0027"},{"line_number":1642,"context_line":"                              \u0027JSON:{\"group_name\": \"group_2\", \"domain_name\": \"default\"}]\u0027)"},{"line_number":1643,"context_line":"}"},{"line_number":1644,"context_line":""},{"line_number":1645,"context_line":"MAPPING_UNICODE \u003d {"},{"line_number":1646,"context_line":"    \"rules\": ["}],"source_content_type":"text/x-python","patch_set":22,"id":"bfdaf3ff_2d15d19c","line":1643,"in_reply_to":"bfdaf3ff_a1cb611c","updated":"2019-01-16 09:48:16.000000000","message":"Done","commit_id":"2e426052c755812a4522961659ad49494322839c"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"af3687591d8ef71dac5c515a7df682f1dc96691d","unresolved":false,"context_lines":[{"line_number":1448,"context_line":"                    \"user\": {"},{"line_number":1449,"context_line":"                        \"name\": \"{0}\","},{"line_number":1450,"context_line":"                        \"domain\": \"{1}\","},{"line_number":1451,"context_line":"                        \"groups\": \"{2}\""},{"line_number":1452,"context_line":"                    }"},{"line_number":1453,"context_line":"                }"},{"line_number":1454,"context_line":"            ],"}],"source_content_type":"text/x-python","patch_set":26,"id":"9fdfeff1_21897ac9","line":1451,"updated":"2019-01-23 13:50:53.000000000","message":"This example does not work for me. Trying to set a local rule like this I get:\n\n Additional properties are not allowed (u\u0027groups\u0027 was unexpected)\n\nIf tests are passing this way then that means the tests need to be fixed to not allow this invalid configuration.\n\nIt needs to be something like:\n\n \"local\": [\n    {\n      \"user\": {\n        \"name\": \"{0}\"\n      }\n    }, {\n      \"groups\": \"{1}\"\n    }\n ]\n\nBut that doesn\u0027t work either when you try to authenticate:\n\n $ openstack token issue\n Invalid rule: {u\u0027groups\u0027: u\u0027[u\\\u0027{\\\u0027, u\\\u0027\"\\\u0027, u\\\u0027J\\\u0027, u\\\u0027S\\\u0027, u\\\u0027O\\\u0027, u\\\u0027N\\\u0027, u\\\u0027\"\\\u0027, u\\\u0027:\\\u0027, u\\\u0027 \\\u0027, u\\\u0027[\\\u0027, u\\\u0027]\\\u0027, u\\\u0027}\\\u0027]\u0027}. Both \u0027groups\u0027 and \u0027domain\u0027 keywords must be specified. (Disable insecure_debug mode to suppress these details.)\n\nAdding the domain keyword also doesn\u0027t fix it and doesn\u0027t make sense anyway because there is no way to get the group domain with this syntax.","commit_id":"7e9890e698655bb91848bed4ef3acab036ee9112"},{"author":{"_account_id":27621,"name":"Vishakha Agarwal","email":"agarwalvishakha18@gmail.com","username":"Vishakha"},"change_message_id":"2c61eabd8174e544f61f0ed138fc3b5a83bfdce9","unresolved":false,"context_lines":[{"line_number":1448,"context_line":"                    \"user\": {"},{"line_number":1449,"context_line":"                        \"name\": \"{0}\","},{"line_number":1450,"context_line":"                        \"domain\": \"{1}\","},{"line_number":1451,"context_line":"                        \"groups\": \"{2}\""},{"line_number":1452,"context_line":"                    }"},{"line_number":1453,"context_line":"                }"},{"line_number":1454,"context_line":"            ],"}],"source_content_type":"text/x-python","patch_set":26,"id":"9fdfeff1_360859d8","line":1451,"in_reply_to":"9fdfeff1_21897ac9","updated":"2019-01-31 06:32:55.000000000","message":"Added the test for validation_schema for this local rule.\n\nBut Yes still I am stuck as the rule is not getting approved due to no domain. Any suggestions?","commit_id":"7e9890e698655bb91848bed4ef3acab036ee9112"},{"author":{"_account_id":27621,"name":"Vishakha Agarwal","email":"agarwalvishakha18@gmail.com","username":"Vishakha"},"change_message_id":"c1ed852f00c9fa080e5cdd2aa0433d409ab2ae1f","unresolved":false,"context_lines":[{"line_number":1448,"context_line":"                    \"user\": {"},{"line_number":1449,"context_line":"                        \"name\": \"{0}\","},{"line_number":1450,"context_line":"                        \"domain\": \"{1}\","},{"line_number":1451,"context_line":"                        \"groups\": \"{2}\""},{"line_number":1452,"context_line":"                    }"},{"line_number":1453,"context_line":"                }"},{"line_number":1454,"context_line":"            ],"}],"source_content_type":"text/x-python","patch_set":26,"id":"9fdfeff1_2a378a4f","line":1451,"in_reply_to":"9fdfeff1_360859d8","updated":"2019-01-31 10:11:40.000000000","message":"Added test case in new patch set.\n\nhttps://review.openstack.org/#/c/634193/","commit_id":"7e9890e698655bb91848bed4ef3acab036ee9112"}],"keystone/tests/unit/saml2/signed_saml2_assertion.xml":[{"author":{"_account_id":15054,"name":"wangxiyuan","email":"wangxiyuan1007@gmail.com","username":"wangxiyuan"},"change_message_id":"5ac182802914e1e356d58bf7060c8e01fbf401cc","unresolved":false,"context_lines":[{"line_number":67,"context_line":"    \u003c/ns0:Attribute\u003e"},{"line_number":68,"context_line":"    \u003cns0:Attribute Name\u003d\"openstack_groups\" NameFormat\u003d\"urn:oasis:names:tc:SAML:2.0:attrname-format:uri\"\u003e"},{"line_number":69,"context_line":"      \u003cns0:AttributeValue xsi:type\u003d\"xs:string\"\u003eJSON:{\"group_name\":\"admin\",\"domain_name\":\"default\"}\u003c/ns0:AttributeValue\u003e"},{"line_number":70,"context_line":"        \u003cns0:AttributeValue xsi:type\u003d\"xs:string\"\u003eJSON:{\"group_name\":\"nonadmin\",\"domain_name\":\"default\"}\u003c/ns0:AttributeValue\u003e"},{"line_number":71,"context_line":"    \u003c/ns0:Attribute\u003e"},{"line_number":72,"context_line":"  \u003c/ns0:AttributeStatement\u003e"},{"line_number":73,"context_line":"\u003c/ns0:Assertion\u003e"}],"source_content_type":"application/xml","patch_set":14,"id":"1f769fc5_eea5d0b6","line":70,"range":{"start_line":70,"start_character":6,"end_line":70,"end_character":8},"updated":"2018-12-26 08:48:16.000000000","message":"L70 should be in the same level as L69","commit_id":"63e1c7f98ce82c83c02619543c5b14a9b643bcf9"},{"author":{"_account_id":27621,"name":"Vishakha Agarwal","email":"agarwalvishakha18@gmail.com","username":"Vishakha"},"change_message_id":"48dcd514ad720c147c17d081ec10b84fe7527f31","unresolved":false,"context_lines":[{"line_number":67,"context_line":"    \u003c/ns0:Attribute\u003e"},{"line_number":68,"context_line":"    \u003cns0:Attribute Name\u003d\"openstack_groups\" NameFormat\u003d\"urn:oasis:names:tc:SAML:2.0:attrname-format:uri\"\u003e"},{"line_number":69,"context_line":"      \u003cns0:AttributeValue xsi:type\u003d\"xs:string\"\u003eJSON:{\"group_name\":\"admin\",\"domain_name\":\"default\"}\u003c/ns0:AttributeValue\u003e"},{"line_number":70,"context_line":"        \u003cns0:AttributeValue xsi:type\u003d\"xs:string\"\u003eJSON:{\"group_name\":\"nonadmin\",\"domain_name\":\"default\"}\u003c/ns0:AttributeValue\u003e"},{"line_number":71,"context_line":"    \u003c/ns0:Attribute\u003e"},{"line_number":72,"context_line":"  \u003c/ns0:AttributeStatement\u003e"},{"line_number":73,"context_line":"\u003c/ns0:Assertion\u003e"}],"source_content_type":"application/xml","patch_set":14,"id":"1f769fc5_f7611c3b","line":70,"range":{"start_line":70,"start_character":6,"end_line":70,"end_character":8},"in_reply_to":"1f769fc5_eea5d0b6","updated":"2018-12-27 06:53:16.000000000","message":"Done","commit_id":"63e1c7f98ce82c83c02619543c5b14a9b643bcf9"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"3757b04c788b0aa3d3dbc3482ea5217cb1a0a27e","unresolved":false,"context_lines":[{"line_number":66,"context_line":"      \u003cns0:AttributeValue xsi:type\u003d\"xs:string\"\u003eproject_domain\u003c/ns0:AttributeValue\u003e"},{"line_number":67,"context_line":"    \u003c/ns0:Attribute\u003e"},{"line_number":68,"context_line":"    \u003cns0:Attribute Name\u003d\"openstack_groups\" NameFormat\u003d\"urn:oasis:names:tc:SAML:2.0:attrname-format:uri\"\u003e"},{"line_number":69,"context_line":"      \u003cns0:AttributeValue xsi:type\u003d\"xs:string\"\u003eJSON:{\"group_name\":\"admin\",\"domain_name\":\"default\"}\u003c/ns0:AttributeValue\u003e"},{"line_number":70,"context_line":"      \u003cns0:AttributeValue xsi:type\u003d\"xs:string\"\u003eJSON:{\"group_name\":\"nonadmin\",\"domain_name\":\"default\"}\u003c/ns0:AttributeValue\u003e"},{"line_number":71,"context_line":"    \u003c/ns0:Attribute\u003e"},{"line_number":72,"context_line":"  \u003c/ns0:AttributeStatement\u003e"}],"source_content_type":"application/xml","patch_set":22,"id":"bfdaf3ff_21d771c2","line":69,"range":{"start_line":69,"start_character":89,"end_line":69,"end_character":96},"updated":"2019-01-11 11:17:29.000000000","message":"nit - the default domain has a name \"Default\" not \"default\", would be better to be consistent (or just pick a whole different domain)","commit_id":"2e426052c755812a4522961659ad49494322839c"},{"author":{"_account_id":27621,"name":"Vishakha Agarwal","email":"agarwalvishakha18@gmail.com","username":"Vishakha"},"change_message_id":"3bc0afdff1d47d48e83a7fec2a151b9e3d6dda76","unresolved":false,"context_lines":[{"line_number":66,"context_line":"      \u003cns0:AttributeValue xsi:type\u003d\"xs:string\"\u003eproject_domain\u003c/ns0:AttributeValue\u003e"},{"line_number":67,"context_line":"    \u003c/ns0:Attribute\u003e"},{"line_number":68,"context_line":"    \u003cns0:Attribute Name\u003d\"openstack_groups\" NameFormat\u003d\"urn:oasis:names:tc:SAML:2.0:attrname-format:uri\"\u003e"},{"line_number":69,"context_line":"      \u003cns0:AttributeValue xsi:type\u003d\"xs:string\"\u003eJSON:{\"group_name\":\"admin\",\"domain_name\":\"default\"}\u003c/ns0:AttributeValue\u003e"},{"line_number":70,"context_line":"      \u003cns0:AttributeValue xsi:type\u003d\"xs:string\"\u003eJSON:{\"group_name\":\"nonadmin\",\"domain_name\":\"default\"}\u003c/ns0:AttributeValue\u003e"},{"line_number":71,"context_line":"    \u003c/ns0:Attribute\u003e"},{"line_number":72,"context_line":"  \u003c/ns0:AttributeStatement\u003e"}],"source_content_type":"application/xml","patch_set":22,"id":"bfdaf3ff_6d22f902","line":69,"range":{"start_line":69,"start_character":89,"end_line":69,"end_character":96},"in_reply_to":"bfdaf3ff_21d771c2","updated":"2019-01-16 09:48:16.000000000","message":"Done","commit_id":"2e426052c755812a4522961659ad49494322839c"}],"keystone/tests/unit/test_v3_federation.py":[{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"3757b04c788b0aa3d3dbc3482ea5217cb1a0a27e","unresolved":false,"context_lines":[{"line_number":3625,"context_line":"    ROLES \u003d [\u0027admin\u0027, \u0027member\u0027]"},{"line_number":3626,"context_line":"    PROJECT \u003d \u0027development\u0027"},{"line_number":3627,"context_line":"    PROJECT_DOMAIN \u003d \u0027project_domain\u0027"},{"line_number":3628,"context_line":"    GROUPS \u003d [\u0027{\"group_name\":\"admin\",\"domain_name\":\"default\"}\u0027,"},{"line_number":3629,"context_line":"              \u0027{\"group_name\":\"nonadmin\",\"domain_name\":\"default\"}\u0027]"},{"line_number":3630,"context_line":"    SAML_GENERATION_ROUTE \u003d \u0027/auth/OS-FEDERATION/saml2\u0027"},{"line_number":3631,"context_line":"    ECP_GENERATION_ROUTE \u003d \u0027/auth/OS-FEDERATION/saml2/ecp\u0027"}],"source_content_type":"text/x-python","patch_set":22,"id":"bfdaf3ff_81ef3d86","line":3628,"range":{"start_line":3628,"start_character":52,"end_line":3628,"end_character":59},"updated":"2019-01-11 11:17:29.000000000","message":"same nitpick about the name here","commit_id":"2e426052c755812a4522961659ad49494322839c"},{"author":{"_account_id":27621,"name":"Vishakha Agarwal","email":"agarwalvishakha18@gmail.com","username":"Vishakha"},"change_message_id":"3bc0afdff1d47d48e83a7fec2a151b9e3d6dda76","unresolved":false,"context_lines":[{"line_number":3625,"context_line":"    ROLES \u003d [\u0027admin\u0027, \u0027member\u0027]"},{"line_number":3626,"context_line":"    PROJECT \u003d \u0027development\u0027"},{"line_number":3627,"context_line":"    PROJECT_DOMAIN \u003d \u0027project_domain\u0027"},{"line_number":3628,"context_line":"    GROUPS \u003d [\u0027{\"group_name\":\"admin\",\"domain_name\":\"default\"}\u0027,"},{"line_number":3629,"context_line":"              \u0027{\"group_name\":\"nonadmin\",\"domain_name\":\"default\"}\u0027]"},{"line_number":3630,"context_line":"    SAML_GENERATION_ROUTE \u003d \u0027/auth/OS-FEDERATION/saml2\u0027"},{"line_number":3631,"context_line":"    ECP_GENERATION_ROUTE \u003d \u0027/auth/OS-FEDERATION/saml2/ecp\u0027"}],"source_content_type":"text/x-python","patch_set":22,"id":"bfdaf3ff_4d7db5e5","line":3628,"range":{"start_line":3628,"start_character":52,"end_line":3628,"end_character":59},"in_reply_to":"bfdaf3ff_81ef3d86","updated":"2019-01-16 09:48:16.000000000","message":"Done","commit_id":"2e426052c755812a4522961659ad49494322839c"}],"releasenotes/notes/bug-1641625-fe463874dc5edb10.yaml":[{"author":{"_account_id":15054,"name":"wangxiyuan","email":"wangxiyuan1007@gmail.com","username":"wangxiyuan"},"change_message_id":"a1e31b61f72e20ac8cf3cc836981da99880b1ada","unresolved":false,"context_lines":[{"line_number":3,"context_line":"  - |"},{"line_number":4,"context_line":"    [`bug 1641625 \u003chttps://bugs.launchpad.net/keystone/+bug/1641625\u003e`_]"},{"line_number":5,"context_line":"    The keystone Idp now includes an additional attribute called \"openstack_user_groups\" "},{"line_number":6,"context_line":"    in the assertion when generating SAML assertions. "}],"source_content_type":"text/x-yaml","patch_set":7,"id":"3f79a3b5_9befbd86","line":6,"updated":"2018-08-06 10:21:20.000000000","message":"remove the extra space","commit_id":"c4e8f804e50c439249a21b538f1b900d8ecbd83b"},{"author":{"_account_id":27621,"name":"Vishakha Agarwal","email":"agarwalvishakha18@gmail.com","username":"Vishakha"},"change_message_id":"c9744506288185ea5932510c9d6ebfba834c1606","unresolved":false,"context_lines":[{"line_number":3,"context_line":"  - |"},{"line_number":4,"context_line":"    [`bug 1641625 \u003chttps://bugs.launchpad.net/keystone/+bug/1641625\u003e`_]"},{"line_number":5,"context_line":"    The keystone Idp now includes an additional attribute called \"openstack_user_groups\" "},{"line_number":6,"context_line":"    in the assertion when generating SAML assertions. "}],"source_content_type":"text/x-yaml","patch_set":7,"id":"3f79a3b5_ad2cc047","line":6,"in_reply_to":"3f79a3b5_9befbd86","updated":"2018-08-06 10:31:26.000000000","message":"done","commit_id":"c4e8f804e50c439249a21b538f1b900d8ecbd83b"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"04b4fdc2d9e5c8a87b931a75e01cb7f8be5b11c2","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":8,"id":"3f79a3b5_132dbf94","line":7,"updated":"2018-08-07 07:30:53.000000000","message":"Since this is adding a new required parameter to a public method I would add an upgrade note about it as well. https://docs.openstack.org/keystone/latest/api/keystone.federation.idp.html#keystone.federation.idp.SAMLGenerator.samlize_token","commit_id":"dc0867114f0b63ae525b46b66285d53c8a9dffc3"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"70928f7c820f670226ddfeeac44ca5d1dfe29211","unresolved":false,"context_lines":[{"line_number":2,"context_line":"features:"},{"line_number":3,"context_line":"  - |"},{"line_number":4,"context_line":"    [`bug 1641625 \u003chttps://bugs.launchpad.net/keystone/+bug/1641625\u003e`_]"},{"line_number":5,"context_line":"    The keystone Idp now includes an additional attribute called `openstack_groups`"},{"line_number":6,"context_line":"    in the assertion when generating SAML assertions."},{"line_number":7,"context_line":""},{"line_number":8,"context_line":"upgrade:"}],"source_content_type":"text/x-yaml","patch_set":11,"id":"3f79a3b5_96558853","line":5,"range":{"start_line":5,"start_character":25,"end_line":5,"end_character":33},"updated":"2018-11-27 19:38:45.000000000","message":"include*","commit_id":"ef69fcc91a7d90c000fcca26b63126df27a8e7e4"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"70928f7c820f670226ddfeeac44ca5d1dfe29211","unresolved":false,"context_lines":[{"line_number":2,"context_line":"features:"},{"line_number":3,"context_line":"  - |"},{"line_number":4,"context_line":"    [`bug 1641625 \u003chttps://bugs.launchpad.net/keystone/+bug/1641625\u003e`_]"},{"line_number":5,"context_line":"    The keystone Idp now includes an additional attribute called `openstack_groups`"},{"line_number":6,"context_line":"    in the assertion when generating SAML assertions."},{"line_number":7,"context_line":""},{"line_number":8,"context_line":"upgrade:"}],"source_content_type":"text/x-yaml","patch_set":11,"id":"3f79a3b5_76522c6c","line":5,"range":{"start_line":5,"start_character":17,"end_line":5,"end_character":20},"updated":"2018-11-27 19:38:45.000000000","message":"nit: keystone identity providers*","commit_id":"ef69fcc91a7d90c000fcca26b63126df27a8e7e4"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"70928f7c820f670226ddfeeac44ca5d1dfe29211","unresolved":false,"context_lines":[{"line_number":3,"context_line":"  - |"},{"line_number":4,"context_line":"    [`bug 1641625 \u003chttps://bugs.launchpad.net/keystone/+bug/1641625\u003e`_]"},{"line_number":5,"context_line":"    The keystone Idp now includes an additional attribute called `openstack_groups`"},{"line_number":6,"context_line":"    in the assertion when generating SAML assertions."},{"line_number":7,"context_line":""},{"line_number":8,"context_line":"upgrade:"},{"line_number":9,"context_line":"  - |"}],"source_content_type":"text/x-yaml","patch_set":11,"id":"3f79a3b5_d6c4600f","line":6,"updated":"2018-11-27 19:38:45.000000000","message":"We should say what exactly the groups are:\n\n The ``openstack_groups`` SAML attribute is a list of JSON\n strings representing the OpenStack groups a user is a\n member of.","commit_id":"ef69fcc91a7d90c000fcca26b63126df27a8e7e4"},{"author":{"_account_id":15054,"name":"wangxiyuan","email":"wangxiyuan1007@gmail.com","username":"wangxiyuan"},"change_message_id":"9f7e20f07951ca173ed1da1c1099b07bcbe8850e","unresolved":false,"context_lines":[{"line_number":5,"context_line":"    The keystone Idp now includes an additional attribute called `openstack_groups`"},{"line_number":6,"context_line":"    in the assertion when generating SAML assertions."},{"line_number":7,"context_line":""},{"line_number":8,"context_line":"upgrade:"},{"line_number":9,"context_line":"  - |"},{"line_number":10,"context_line":"    [`bug 1641625 \u003chttps://bugs.launchpad.net/keystone/+bug/1641625\u003e`_]"},{"line_number":11,"context_line":"    A new attribute, `openstack_groups`, is added to SAML assertion for the"}],"source_content_type":"text/x-yaml","patch_set":11,"id":"3f79a3b5_999c2d5d","line":8,"range":{"start_line":8,"start_character":0,"end_line":8,"end_character":8},"updated":"2018-11-22 03:54:17.000000000","message":"not sure how is it relate to Upgrade?","commit_id":"ef69fcc91a7d90c000fcca26b63126df27a8e7e4"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"70e863aa44777273d16a1ddb929abea5c1d4fc2d","unresolved":false,"context_lines":[{"line_number":5,"context_line":"    The keystone Idp now includes an additional attribute called `openstack_groups`"},{"line_number":6,"context_line":"    in the assertion when generating SAML assertions."},{"line_number":7,"context_line":""},{"line_number":8,"context_line":"upgrade:"},{"line_number":9,"context_line":"  - |"},{"line_number":10,"context_line":"    [`bug 1641625 \u003chttps://bugs.launchpad.net/keystone/+bug/1641625\u003e`_]"},{"line_number":11,"context_line":"    A new attribute, `openstack_groups`, is added to SAML assertion for the"}],"source_content_type":"text/x-yaml","patch_set":11,"id":"3f79a3b5_7f9f03b2","line":8,"range":{"start_line":8,"start_character":0,"end_line":8,"end_character":8},"in_reply_to":"3f79a3b5_999c2d5d","updated":"2018-12-03 08:54:56.000000000","message":"Agreed, upgrade release notes are for when an operator needs to take action to prepare for the change.","commit_id":"ef69fcc91a7d90c000fcca26b63126df27a8e7e4"},{"author":{"_account_id":15054,"name":"wangxiyuan","email":"wangxiyuan1007@gmail.com","username":"wangxiyuan"},"change_message_id":"5ac182802914e1e356d58bf7060c8e01fbf401cc","unresolved":false,"context_lines":[{"line_number":5,"context_line":"    The keystone Idp now includes an additional attribute called `openstack_groups`"},{"line_number":6,"context_line":"    in the assertion when generating SAML assertions."},{"line_number":7,"context_line":""},{"line_number":8,"context_line":"upgrade:"},{"line_number":9,"context_line":"  - |"},{"line_number":10,"context_line":"    [`bug 1641625 \u003chttps://bugs.launchpad.net/keystone/+bug/1641625\u003e`_]"},{"line_number":11,"context_line":"    A new attribute, `openstack_groups`, is added to SAML assertion for the"}],"source_content_type":"text/x-yaml","patch_set":14,"id":"1f769fc5_6e91c052","line":8,"updated":"2018-12-26 08:48:16.000000000","message":"again, I don\u0027t think this change will impact keystone upgrade.","commit_id":"63e1c7f98ce82c83c02619543c5b14a9b643bcf9"},{"author":{"_account_id":27621,"name":"Vishakha Agarwal","email":"agarwalvishakha18@gmail.com","username":"Vishakha"},"change_message_id":"48dcd514ad720c147c17d081ec10b84fe7527f31","unresolved":false,"context_lines":[{"line_number":5,"context_line":"    The keystone Idp now includes an additional attribute called `openstack_groups`"},{"line_number":6,"context_line":"    in the assertion when generating SAML assertions."},{"line_number":7,"context_line":""},{"line_number":8,"context_line":"upgrade:"},{"line_number":9,"context_line":"  - |"},{"line_number":10,"context_line":"    [`bug 1641625 \u003chttps://bugs.launchpad.net/keystone/+bug/1641625\u003e`_]"},{"line_number":11,"context_line":"    A new attribute, `openstack_groups`, is added to SAML assertion for the"}],"source_content_type":"text/x-yaml","patch_set":14,"id":"1f769fc5_1767f84f","line":8,"in_reply_to":"1f769fc5_6e91c052","updated":"2018-12-27 06:53:16.000000000","message":"done","commit_id":"63e1c7f98ce82c83c02619543c5b14a9b643bcf9"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"0076a3a5428378510090ce82297059c60537d1ab","unresolved":false,"context_lines":[{"line_number":2,"context_line":"features:"},{"line_number":3,"context_line":"  - |"},{"line_number":4,"context_line":"    [`bug 1641625 \u003chttps://bugs.launchpad.net/keystone/+bug/1641625\u003e`_]"},{"line_number":5,"context_line":"    The keystone Idp now includes an additional attribute called `openstack_groups`"},{"line_number":6,"context_line":"    in the assertion when generating SAML assertions."}],"source_content_type":"text/x-yaml","patch_set":17,"id":"dfd5e7cf_5456ec08","line":5,"range":{"start_line":5,"start_character":17,"end_line":5,"end_character":20},"updated":"2019-01-07 15:42:00.000000000","message":"keystone configured as an Identity Provider*","commit_id":"32fd95cd58d35d6d72bca8f0b233e5cdcdc76053"},{"author":{"_account_id":27621,"name":"Vishakha Agarwal","email":"agarwalvishakha18@gmail.com","username":"Vishakha"},"change_message_id":"f8518ef1fe63660dda9cc946c699d1f4e83bc189","unresolved":false,"context_lines":[{"line_number":2,"context_line":"features:"},{"line_number":3,"context_line":"  - |"},{"line_number":4,"context_line":"    [`bug 1641625 \u003chttps://bugs.launchpad.net/keystone/+bug/1641625\u003e`_]"},{"line_number":5,"context_line":"    The keystone Idp now includes an additional attribute called `openstack_groups`"},{"line_number":6,"context_line":"    in the assertion when generating SAML assertions."}],"source_content_type":"text/x-yaml","patch_set":17,"id":"dfd5e7cf_20abcb1d","line":5,"range":{"start_line":5,"start_character":17,"end_line":5,"end_character":20},"in_reply_to":"dfd5e7cf_5456ec08","updated":"2019-01-08 16:12:51.000000000","message":"Done","commit_id":"32fd95cd58d35d6d72bca8f0b233e5cdcdc76053"}]}
