)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":28356,"name":"Rafael Weingartner","email":"rafael@apache.org","username":"rafaelweingartner"},"change_message_id":"31712bfe5784aa41b498d7384a002a88d8edfc24","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":10,"id":"c2f98267_5d099fc3","updated":"2025-09-08 10:34:08.000000000","message":"Hello Keystone team. \nWhat would be the next steps on this one to get it merged?","commit_id":"d23a14b8969d201b06097cee1ca0d84fe21f915c"},{"author":{"_account_id":28356,"name":"Rafael Weingartner","email":"rafael@apache.org","username":"rafaelweingartner"},"change_message_id":"9e199f70935148e47398e01de6a67bba9ad1841e","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":10,"id":"d349463b_dd30970f","updated":"2025-08-20 10:39:13.000000000","message":"Hello guys, \nI have rebased this patch. Everything seems to be fine here now. This patch implements a spec that was merge quite a while ago.","commit_id":"d23a14b8969d201b06097cee1ca0d84fe21f915c"},{"author":{"_account_id":28356,"name":"Rafael Weingartner","email":"rafael@apache.org","username":"rafaelweingartner"},"change_message_id":"c93e4ec4aee26d3c87e66eaabe62b13d0ef35ed1","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":11,"id":"d3efe3da_9464795a","updated":"2025-12-10 13:20:24.000000000","message":"Artem, thanks for your valuable review!\n\nI have added documentation on how to use this feature with one IdP (Keycloak), which is the IdP we use. \n\nMoreover, I have responded to your inquiries, and I added some tests for the projects_json definition as String.\n\nI have not merged the options projects_json with projects to avoid mixing the implementation and to take advantage of the schema version. Therefore, when this is merged, and somebody upgrades in production, the new code is not activated. I think that is safer and more secure than merging the workflows.\n\nIf you have something else to ask here , let me know.\n\nAlso, if you need help using/testing this one, you can ping me, and I can help you setup this with the IdP of your choice.","commit_id":"f1822c1b30acbef803d82445f9cd55f0afe39fdd"},{"author":{"_account_id":27900,"name":"Artem Goncharov","email":"artem.goncharov@gmail.com","username":"gtema"},"change_message_id":"0a692a39710429e22c7ca9212d7555aaa8a2529f","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":11,"id":"14c9bc87_b8f2c05c","updated":"2025-10-30 11:27:28.000000000","message":"Documentation is desperately needed in this change. Without it reviewing it is hard. Users would have absolutely no chance start using it in any way.\nIt would be nice to at least hint how projects_json can be generated on the idp side - I guess this is one of the most complex things. That also means there is no chance test it functionally.\nAnd we have agreed in the spec that the \u0027projects\u0027 attribute is being extended and not that \u0027projects_json\u0027 is being add.","commit_id":"f1822c1b30acbef803d82445f9cd55f0afe39fdd"},{"author":{"_account_id":28356,"name":"Rafael Weingartner","email":"rafael@apache.org","username":"rafaelweingartner"},"change_message_id":"6fe95fef2324be8d99997d4e9e1883a174444daa","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":11,"id":"3ccbd03c_b4f9a000","updated":"2025-10-22 10:24:16.000000000","message":"Hello guys, \nThis is a friendly reminder of this patch. It is ready for your review, and it would be nice for us to get it merged as the spec was already merged a long time ago.","commit_id":"f1822c1b30acbef803d82445f9cd55f0afe39fdd"},{"author":{"_account_id":28356,"name":"Rafael Weingartner","email":"rafael@apache.org","username":"rafaelweingartner"},"change_message_id":"c7222d83fcfcb15779defd1e745f63d1edbe8832","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":11,"id":"5928c340_537bb880","updated":"2025-10-03 16:16:43.000000000","message":"hello guys, I have rebased this patch. This is an important one to get merged as the spec has been merged a long time ago already.","commit_id":"f1822c1b30acbef803d82445f9cd55f0afe39fdd"},{"author":{"_account_id":28356,"name":"Rafael Weingartner","email":"rafael@apache.org","username":"rafaelweingartner"},"change_message_id":"b5d9e81eead6ada6eabd8aa026192030e0cbe262","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":11,"id":"f55e71fb_5daf3886","in_reply_to":"14c9bc87_b8f2c05c","updated":"2025-12-10 13:17:09.000000000","message":"Thanks for the review. I added the documentation on how to generate the custom JSON string in the IdP.\n\nBear in mind that this is out of the scope of Keystone, and one should know how to handle/configure their selected IdP. Therefore, I am presenting a mini tutorial on how to generate such message in Keycloak, with a specific pattern that we adopt in our integrations of Keycloak and Keystone.\n\n\u003e And we have agreed in the spec that the \u0027projects\u0027 attribute is being extended and not that \u0027projects_json\u0027 is being add\n\nRegarding this part here, I maintained it to facilitate the tests on our side, as everything was already prepared with `projects_json`. However, both will work.","commit_id":"f1822c1b30acbef803d82445f9cd55f0afe39fdd"},{"author":{"_account_id":5890,"name":"Doug Goldstein","email":"cardoe@cardoe.com","username":"cardoe"},"change_message_id":"c04f17c9fe7ffd3097846f214d549a74e5553c9c","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":13,"id":"108feb70_6644cd96","updated":"2025-12-10 14:47:14.000000000","message":"Can we spell the name of the documentation file correctly? That\u0027s going to be difficult when searching for things.","commit_id":"b9348dee5d49f2abd47a8575589a7fae10c278ba"},{"author":{"_account_id":28356,"name":"Rafael Weingartner","email":"rafael@apache.org","username":"rafaelweingartner"},"change_message_id":"85ab35a6535fdbc22dad21233a3746881852cc05","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":13,"id":"ad866276_0f348958","in_reply_to":"108feb70_6644cd96","updated":"2025-12-10 16:03:26.000000000","message":"Thanks for catching this one. I fixed the documentation file name.","commit_id":"b9348dee5d49f2abd47a8575589a7fae10c278ba"},{"author":{"_account_id":28356,"name":"Rafael Weingartner","email":"rafael@apache.org","username":"rafaelweingartner"},"change_message_id":"990381a2f0b704fc8794e52e63903ef44d513418","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":13,"id":"e04f8aa7_cb1a1f4a","in_reply_to":"ad866276_0f348958","updated":"2025-12-10 16:04:08.000000000","message":"Done","commit_id":"b9348dee5d49f2abd47a8575589a7fae10c278ba"},{"author":{"_account_id":28356,"name":"Rafael Weingartner","email":"rafael@apache.org","username":"rafaelweingartner"},"change_message_id":"b459e0fadc14910494b570d3c8ad74dc0fe8b49f","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":14,"id":"b2e7f487_0d0e17e9","updated":"2026-01-26 12:26:27.000000000","message":"Thanks Grzegorz!\n\nIf you guys need any assistance with the integration of Keycloak and Keystone; let me know, and I can try to help you all.\n\nEager to see this one merged \u003d), and then to propose other improvements we did on top of this one.","commit_id":"58d697fd34d15b5b21ff36caaf2743062764ec83"},{"author":{"_account_id":28356,"name":"Rafael Weingartner","email":"rafael@apache.org","username":"rafaelweingartner"},"change_message_id":"a29482c29afb5ef8df6be38cca9259caa3811324","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":15,"id":"9bd69035_a441022e","updated":"2026-02-16 13:52:23.000000000","message":"Hello guys, \nAbout this one, do you want some other addition or changes here?","commit_id":"e6a15ba337bbf7950e707b04bbbe3ea609b9a131"},{"author":{"_account_id":28356,"name":"Rafael Weingartner","email":"rafael@apache.org","username":"rafaelweingartner"},"change_message_id":"61c6f05aa9280288656eeaf705fa97da07133c51","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":15,"id":"3052c91c_c464490a","updated":"2026-03-10 11:22:58.000000000","message":"Thank you so much guys!!!\n\nThis will free us to propose other improvements to Keystone and related components","commit_id":"e6a15ba337bbf7950e707b04bbbe3ea609b9a131"},{"author":{"_account_id":28356,"name":"Rafael Weingartner","email":"rafael@apache.org","username":"rafaelweingartner"},"change_message_id":"0c54ba3f352d25f0b3e95a4f1f9c1bade9f637a1","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":15,"id":"9abe3fa6_43f731b7","updated":"2026-02-22 19:55:17.000000000","message":"Thanks Grzegorz Grasza for the previous review. Are you still with a +2 on this one?","commit_id":"e6a15ba337bbf7950e707b04bbbe3ea609b9a131"},{"author":{"_account_id":28356,"name":"Rafael Weingartner","email":"rafael@apache.org","username":"rafaelweingartner"},"change_message_id":"4d152e155e31d11fd7f338dfb4080c00d7ac9075","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":15,"id":"43d36aee_fee947ac","updated":"2026-03-06 14:12:36.000000000","message":"Thanks for the review David!","commit_id":"e6a15ba337bbf7950e707b04bbbe3ea609b9a131"}],"doc/source/admin/federation/dynamic_project_assignments.rst":[{"author":{"_account_id":14250,"name":"Grzegorz Grasza","email":"xek@redhat.com","username":"xek"},"change_message_id":"9fefe9ffb92a6e762497b119c854fb64857193f1","unresolved":true,"context_lines":[{"line_number":144,"context_line":"    print(\"Projects and permissions to be disseminated to Keystone: [\" + JSON.stringify(all_projects_list) + \"].\")"},{"line_number":145,"context_line":"    exports \u003d JSON.stringify(all_projects_list);"},{"line_number":146,"context_line":""},{"line_number":147,"context_line":"The above script will assume an attribute structure that may not have a domain defined; therefore, instead of ``\u003copenstack_domain_name\u003e.\u003copenstack_project_name\u003e.\u003copenstack_role_name\u003e``, one might have ``\u003c\u003copenstack_project_name\u003e.\u003copenstack_role_name\u003e``. Also, we assume that if the user has multiple roles in the same project, we will repeat the entries in the attribute list in Keycloak. Therefore, we need to handle all of these situations when processing all attributes and generating the JSON structure needed for Keystone."},{"line_number":148,"context_line":""},{"line_number":149,"context_line":"It is important to mention that the script can be simplified and used to generate the JSON as needed. One can work with different data structure in Keycloak, and generate the message required by Keystone. The most important part it ``exports \u003d JSON.stringify(all_projects_list)``, which is the part of the code that generate the JSON string that will be sent to Keystone, after the authentication process."},{"line_number":150,"context_line":""}],"source_content_type":"text/x-rst","patch_set":14,"id":"bb826900_22db4a67","line":147,"range":{"start_line":147,"start_character":203,"end_line":147,"end_character":205},"updated":"2026-01-26 12:31:18.000000000","message":"nit: should be single \u003c","commit_id":"58d697fd34d15b5b21ff36caaf2743062764ec83"},{"author":{"_account_id":28356,"name":"Rafael Weingartner","email":"rafael@apache.org","username":"rafaelweingartner"},"change_message_id":"37703e9ea0facf19455c673c8dda3dfd56efc1d5","unresolved":false,"context_lines":[{"line_number":144,"context_line":"    print(\"Projects and permissions to be disseminated to Keystone: [\" + JSON.stringify(all_projects_list) + \"].\")"},{"line_number":145,"context_line":"    exports \u003d JSON.stringify(all_projects_list);"},{"line_number":146,"context_line":""},{"line_number":147,"context_line":"The above script will assume an attribute structure that may not have a domain defined; therefore, instead of ``\u003copenstack_domain_name\u003e.\u003copenstack_project_name\u003e.\u003copenstack_role_name\u003e``, one might have ``\u003c\u003copenstack_project_name\u003e.\u003copenstack_role_name\u003e``. Also, we assume that if the user has multiple roles in the same project, we will repeat the entries in the attribute list in Keycloak. Therefore, we need to handle all of these situations when processing all attributes and generating the JSON structure needed for Keystone."},{"line_number":148,"context_line":""},{"line_number":149,"context_line":"It is important to mention that the script can be simplified and used to generate the JSON as needed. One can work with different data structure in Keycloak, and generate the message required by Keystone. The most important part it ``exports \u003d JSON.stringify(all_projects_list)``, which is the part of the code that generate the JSON string that will be sent to Keystone, after the authentication process."},{"line_number":150,"context_line":""}],"source_content_type":"text/x-rst","patch_set":14,"id":"648686bd_c1277939","line":147,"range":{"start_line":147,"start_character":203,"end_line":147,"end_character":205},"in_reply_to":"bb826900_22db4a67","updated":"2026-01-26 12:40:27.000000000","message":"Done","commit_id":"58d697fd34d15b5b21ff36caaf2743062764ec83"}],"doc/source/admin/federation/mapping_combinations.rst":[{"author":{"_account_id":14250,"name":"Grzegorz Grasza","email":"xek@redhat.com","username":"xek"},"change_message_id":"9fefe9ffb92a6e762497b119c854fb64857193f1","unresolved":true,"context_lines":[{"line_number":1048,"context_line":""},{"line_number":1049,"context_line":"* ``2.0``:  this rule processor is designed to handle the `domain` attribute configured at the root of the attribute mapping. When this attribute is configured, we should take it as the default one for the attribute mapping, instead of the domain of the IdP. Moreover, we should respect the override to it that can take place at the `groups`, `user`, and `projects` attributes definition."},{"line_number":1050,"context_line":""},{"line_number":1051,"context_line":"* `3.0``:  this rule processor is designed to handle the `project_json` attribute configured at the root of the attribute mapping. When this attribute is configured, we load it (the JSON that it contains) and append it to the possible set of hard-coded projects that we find at `projects` property."}],"source_content_type":"text/x-rst","patch_set":14,"id":"3d0928b5_8a053a7e","line":1051,"range":{"start_line":1051,"start_character":2,"end_line":1051,"end_character":3},"updated":"2026-01-26 12:31:18.000000000","message":"nit: missing backtick","commit_id":"58d697fd34d15b5b21ff36caaf2743062764ec83"},{"author":{"_account_id":28356,"name":"Rafael Weingartner","email":"rafael@apache.org","username":"rafaelweingartner"},"change_message_id":"37703e9ea0facf19455c673c8dda3dfd56efc1d5","unresolved":false,"context_lines":[{"line_number":1048,"context_line":""},{"line_number":1049,"context_line":"* ``2.0``:  this rule processor is designed to handle the `domain` attribute configured at the root of the attribute mapping. When this attribute is configured, we should take it as the default one for the attribute mapping, instead of the domain of the IdP. Moreover, we should respect the override to it that can take place at the `groups`, `user`, and `projects` attributes definition."},{"line_number":1050,"context_line":""},{"line_number":1051,"context_line":"* `3.0``:  this rule processor is designed to handle the `project_json` attribute configured at the root of the attribute mapping. When this attribute is configured, we load it (the JSON that it contains) and append it to the possible set of hard-coded projects that we find at `projects` property."}],"source_content_type":"text/x-rst","patch_set":14,"id":"56c3c488_46e4fde7","line":1051,"range":{"start_line":1051,"start_character":2,"end_line":1051,"end_character":3},"in_reply_to":"3d0928b5_8a053a7e","updated":"2026-01-26 12:40:27.000000000","message":"Done","commit_id":"58d697fd34d15b5b21ff36caaf2743062764ec83"}],"keystone/auth/plugins/mapped.py":[{"author":{"_account_id":14250,"name":"Grzegorz Grasza","email":"xek@redhat.com","username":"xek"},"change_message_id":"9fefe9ffb92a6e762497b119c854fb64857193f1","unresolved":true,"context_lines":[{"line_number":241,"context_line":"                    \"removed from the IdP, but the user still has the \""},{"line_number":242,"context_line":"                    \"permission in OpenStack. One should consider \""},{"line_number":243,"context_line":"                    \"migrating to attribute mapping schema version \""},{"line_number":244,"context_line":"                    \"\u00271.2\u0027.\","},{"line_number":245,"context_line":"                    assignment[\u0027role_id\u0027],"},{"line_number":246,"context_line":"                    user,"},{"line_number":247,"context_line":"                    project,"}],"source_content_type":"text/x-python","patch_set":14,"id":"9f7e3eff_ad7ac34b","line":244,"range":{"start_line":244,"start_character":22,"end_line":244,"end_character":25},"updated":"2026-01-26 12:31:18.000000000","message":"this should say 3.0?","commit_id":"58d697fd34d15b5b21ff36caaf2743062764ec83"},{"author":{"_account_id":28356,"name":"Rafael Weingartner","email":"rafael@apache.org","username":"rafaelweingartner"},"change_message_id":"37703e9ea0facf19455c673c8dda3dfd56efc1d5","unresolved":false,"context_lines":[{"line_number":241,"context_line":"                    \"removed from the IdP, but the user still has the \""},{"line_number":242,"context_line":"                    \"permission in OpenStack. One should consider \""},{"line_number":243,"context_line":"                    \"migrating to attribute mapping schema version \""},{"line_number":244,"context_line":"                    \"\u00271.2\u0027.\","},{"line_number":245,"context_line":"                    assignment[\u0027role_id\u0027],"},{"line_number":246,"context_line":"                    user,"},{"line_number":247,"context_line":"                    project,"}],"source_content_type":"text/x-python","patch_set":14,"id":"18a0b34e_9a85f985","line":244,"range":{"start_line":244,"start_character":22,"end_line":244,"end_character":25},"in_reply_to":"9f7e3eff_ad7ac34b","updated":"2026-01-26 12:40:27.000000000","message":"Done","commit_id":"58d697fd34d15b5b21ff36caaf2743062764ec83"},{"author":{"_account_id":14250,"name":"Grzegorz Grasza","email":"xek@redhat.com","username":"xek"},"change_message_id":"9fefe9ffb92a6e762497b119c854fb64857193f1","unresolved":true,"context_lines":[{"line_number":369,"context_line":"        LOG.debug("},{"line_number":370,"context_line":"            \"We are not going to remove left overs project \""},{"line_number":371,"context_line":"            \"assignments because the attribute mapping is \""},{"line_number":372,"context_line":"            \"using a schema version lower than \u00271.2\u0027.\""},{"line_number":373,"context_line":"        )"},{"line_number":374,"context_line":""},{"line_number":375,"context_line":""}],"source_content_type":"text/x-python","patch_set":14,"id":"e7cb4d74_69e8afa6","line":372,"range":{"start_line":372,"start_character":48,"end_line":372,"end_character":51},"updated":"2026-01-26 12:31:18.000000000","message":"this should say 3.0?","commit_id":"58d697fd34d15b5b21ff36caaf2743062764ec83"},{"author":{"_account_id":28356,"name":"Rafael Weingartner","email":"rafael@apache.org","username":"rafaelweingartner"},"change_message_id":"37703e9ea0facf19455c673c8dda3dfd56efc1d5","unresolved":false,"context_lines":[{"line_number":369,"context_line":"        LOG.debug("},{"line_number":370,"context_line":"            \"We are not going to remove left overs project \""},{"line_number":371,"context_line":"            \"assignments because the attribute mapping is \""},{"line_number":372,"context_line":"            \"using a schema version lower than \u00271.2\u0027.\""},{"line_number":373,"context_line":"        )"},{"line_number":374,"context_line":""},{"line_number":375,"context_line":""}],"source_content_type":"text/x-python","patch_set":14,"id":"4d8d9722_5cbc75ca","line":372,"range":{"start_line":372,"start_character":48,"end_line":372,"end_character":51},"in_reply_to":"e7cb4d74_69e8afa6","updated":"2026-01-26 12:40:27.000000000","message":"Done","commit_id":"58d697fd34d15b5b21ff36caaf2743062764ec83"}],"keystone/federation/utils.py":[{"author":{"_account_id":27900,"name":"Artem Goncharov","email":"artem.goncharov@gmail.com","username":"gtema"},"change_message_id":"0a692a39710429e22c7ca9212d7555aaa8a2529f","unresolved":true,"context_lines":[{"line_number":68,"context_line":"}"},{"line_number":69,"context_line":"DEFAULT_SCHEMA_VERSION \u003d \"1.0\""},{"line_number":70,"context_line":"SCHEMA_VERSION_HONOUR_DOMAIN \u003d \"2.0\""},{"line_number":71,"context_line":"SCHEMA_VERSION_SYNC_PROJECT_ASSIGNMENTS_WITH_IDP_STATE \u003d \"3.0\""},{"line_number":72,"context_line":""},{"line_number":73,"context_line":"IDP_ATTRIBUTE_MAPPING_SCHEMA_1_0 \u003d {"},{"line_number":74,"context_line":"    \"type\": \"object\","}],"source_content_type":"text/x-python","patch_set":11,"id":"7e76e85e_68117479","line":71,"updated":"2025-10-30 11:27:28.000000000","message":"nit: not sure we ever even thought of versioning scheme here. I am just wondering whether it is really required to raise the major version (whether it is a major as such) when we add new field (more on that later)","commit_id":"f1822c1b30acbef803d82445f9cd55f0afe39fdd"},{"author":{"_account_id":28356,"name":"Rafael Weingartner","email":"rafael@apache.org","username":"rafaelweingartner"},"change_message_id":"b5d9e81eead6ada6eabd8aa026192030e0cbe262","unresolved":false,"context_lines":[{"line_number":68,"context_line":"}"},{"line_number":69,"context_line":"DEFAULT_SCHEMA_VERSION \u003d \"1.0\""},{"line_number":70,"context_line":"SCHEMA_VERSION_HONOUR_DOMAIN \u003d \"2.0\""},{"line_number":71,"context_line":"SCHEMA_VERSION_SYNC_PROJECT_ASSIGNMENTS_WITH_IDP_STATE \u003d \"3.0\""},{"line_number":72,"context_line":""},{"line_number":73,"context_line":"IDP_ATTRIBUTE_MAPPING_SCHEMA_1_0 \u003d {"},{"line_number":74,"context_line":"    \"type\": \"object\","}],"source_content_type":"text/x-python","patch_set":11,"id":"0a590fe0_e4f28402","line":71,"in_reply_to":"7e76e85e_68117479","updated":"2025-12-10 13:17:09.000000000","message":"In the spec that was merged and approved, it considers the new schema versioning to separate the code and processing of the feature. I would rather maintain these workflows separately. Otherwise, we would need to add more complexity to the schema validation to accept either a string or a complex object structure in the `projects` attributes.","commit_id":"f1822c1b30acbef803d82445f9cd55f0afe39fdd"},{"author":{"_account_id":27900,"name":"Artem Goncharov","email":"artem.goncharov@gmail.com","username":"gtema"},"change_message_id":"0a692a39710429e22c7ca9212d7555aaa8a2529f","unresolved":true,"context_lines":[{"line_number":227,"context_line":""},{"line_number":228,"context_line":"IDP_ATTRIBUTE_MAPPING_SCHEMA_3_0[\u0027properties\u0027][\u0027rules\u0027][\u0027items\u0027][\u0027properties\u0027]["},{"line_number":229,"context_line":"    \u0027local\u0027"},{"line_number":230,"context_line":"][\u0027items\u0027][\u0027properties\u0027][\u0027projects_json\u0027] \u003d {\"type\": \"string\"}"},{"line_number":231,"context_line":""},{"line_number":232,"context_line":""},{"line_number":233,"context_line":"def get_default_attribute_mapping_schema_version():"}],"source_content_type":"text/x-python","patch_set":11,"id":"a2e54d47_23c52d7f","line":230,"updated":"2025-10-30 11:27:28.000000000","message":"I am very confused here. Is it a really a string? Code handling it is pretty veiled, test as well. And unfortunately there is absolutely no documentation added on how the feature is supposed to be used. Last, but not least, in the spec we agreed that the \u0027projects\u0027 fields is object or a string and NOT that \u0027projects_json\u0027 is being added.","commit_id":"f1822c1b30acbef803d82445f9cd55f0afe39fdd"},{"author":{"_account_id":28356,"name":"Rafael Weingartner","email":"rafael@apache.org","username":"rafaelweingartner"},"change_message_id":"b5d9e81eead6ada6eabd8aa026192030e0cbe262","unresolved":false,"context_lines":[{"line_number":227,"context_line":""},{"line_number":228,"context_line":"IDP_ATTRIBUTE_MAPPING_SCHEMA_3_0[\u0027properties\u0027][\u0027rules\u0027][\u0027items\u0027][\u0027properties\u0027]["},{"line_number":229,"context_line":"    \u0027local\u0027"},{"line_number":230,"context_line":"][\u0027items\u0027][\u0027properties\u0027][\u0027projects_json\u0027] \u003d {\"type\": \"string\"}"},{"line_number":231,"context_line":""},{"line_number":232,"context_line":""},{"line_number":233,"context_line":"def get_default_attribute_mapping_schema_version():"}],"source_content_type":"text/x-python","patch_set":11,"id":"38cf4866_8d9dbf2a","line":230,"in_reply_to":"a2e54d47_23c52d7f","updated":"2025-12-10 13:17:09.000000000","message":"As defined in the spec, it is a JSON string that has the `projects` structure. I wrote a documentation showing how to configure Keycloak (it is the IdP we use), to generate such message.","commit_id":"f1822c1b30acbef803d82445f9cd55f0afe39fdd"},{"author":{"_account_id":27900,"name":"Artem Goncharov","email":"artem.goncharov@gmail.com","username":"gtema"},"change_message_id":"0a692a39710429e22c7ca9212d7555aaa8a2529f","unresolved":true,"context_lines":[{"line_number":1102,"context_line":"        \"schema\": IDP_ATTRIBUTE_MAPPING_SCHEMA_1_0,"},{"line_number":1103,"context_line":"        \"processor\": RuleProcessor,"},{"line_number":1104,"context_line":"    },"},{"line_number":1105,"context_line":"    SCHEMA_VERSION_HONOUR_DOMAIN: {"},{"line_number":1106,"context_line":"        \"schema\": IDP_ATTRIBUTE_MAPPING_SCHEMA_2_0,"},{"line_number":1107,"context_line":"        \"processor\": RuleProcessorToHonorDomainOption,"},{"line_number":1108,"context_line":"    },"}],"source_content_type":"text/x-python","patch_set":11,"id":"6f9f29c6_f4f76706","line":1105,"updated":"2025-10-30 11:27:28.000000000","message":"commonwealth English is pretty uncommon in our code. My first reaction to that was that it is a typo.","commit_id":"f1822c1b30acbef803d82445f9cd55f0afe39fdd"},{"author":{"_account_id":28356,"name":"Rafael Weingartner","email":"rafael@apache.org","username":"rafaelweingartner"},"change_message_id":"b5d9e81eead6ada6eabd8aa026192030e0cbe262","unresolved":false,"context_lines":[{"line_number":1102,"context_line":"        \"schema\": IDP_ATTRIBUTE_MAPPING_SCHEMA_1_0,"},{"line_number":1103,"context_line":"        \"processor\": RuleProcessor,"},{"line_number":1104,"context_line":"    },"},{"line_number":1105,"context_line":"    SCHEMA_VERSION_HONOUR_DOMAIN: {"},{"line_number":1106,"context_line":"        \"schema\": IDP_ATTRIBUTE_MAPPING_SCHEMA_2_0,"},{"line_number":1107,"context_line":"        \"processor\": RuleProcessorToHonorDomainOption,"},{"line_number":1108,"context_line":"    },"}],"source_content_type":"text/x-python","patch_set":11,"id":"803ed21b_e8464245","line":1105,"in_reply_to":"6f9f29c6_f4f76706","updated":"2025-12-10 13:17:09.000000000","message":"Done","commit_id":"f1822c1b30acbef803d82445f9cd55f0afe39fdd"}],"keystone/tests/unit/auth/plugins/test_mapped.py":[{"author":{"_account_id":27900,"name":"Artem Goncharov","email":"artem.goncharov@gmail.com","username":"gtema"},"change_message_id":"0a692a39710429e22c7ca9212d7555aaa8a2529f","unresolved":true,"context_lines":[{"line_number":178,"context_line":"        project[\u0027id\u0027] \u003d uuid.uuid4().hex"},{"line_number":179,"context_line":"        return project"},{"line_number":180,"context_line":""},{"line_number":181,"context_line":"    def test_handle_projects_from_mapping_project_exists_add_new_role(self):"},{"line_number":182,"context_line":"        project_mock_1 \u003d self.create_project_mock_for_shadow_project("},{"line_number":183,"context_line":"            self.shadow_project_in_domain_mock"},{"line_number":184,"context_line":"        )"}],"source_content_type":"text/x-python","patch_set":11,"id":"a0ae8f4c_97077078","line":181,"updated":"2025-10-30 11:27:28.000000000","message":"I would love to see a test that verbosely specifies the projects structure in the new form verifying that grants are added/removed. The test in the current form is hiding the relation to the 3.0 mapping","commit_id":"f1822c1b30acbef803d82445f9cd55f0afe39fdd"},{"author":{"_account_id":28356,"name":"Rafael Weingartner","email":"rafael@apache.org","username":"rafaelweingartner"},"change_message_id":"b5d9e81eead6ada6eabd8aa026192030e0cbe262","unresolved":false,"context_lines":[{"line_number":178,"context_line":"        project[\u0027id\u0027] \u003d uuid.uuid4().hex"},{"line_number":179,"context_line":"        return project"},{"line_number":180,"context_line":""},{"line_number":181,"context_line":"    def test_handle_projects_from_mapping_project_exists_add_new_role(self):"},{"line_number":182,"context_line":"        project_mock_1 \u003d self.create_project_mock_for_shadow_project("},{"line_number":183,"context_line":"            self.shadow_project_in_domain_mock"},{"line_number":184,"context_line":"        )"}],"source_content_type":"text/x-python","patch_set":11,"id":"7c3656d9_e40326d9","line":181,"in_reply_to":"a0ae8f4c_97077078","updated":"2025-12-10 13:17:09.000000000","message":"In this part of the tests, the data was already extracted from the IdP. Therefore, it is not here that the JSON/IdP data is processed and prepared for this workflow.","commit_id":"f1822c1b30acbef803d82445f9cd55f0afe39fdd"}],"keystone/tests/unit/federation/test_utils.py":[{"author":{"_account_id":27900,"name":"Artem Goncharov","email":"artem.goncharov@gmail.com","username":"gtema"},"change_message_id":"0a692a39710429e22c7ca9212d7555aaa8a2529f","unresolved":true,"context_lines":[{"line_number":110,"context_line":"        identity_values \u003d {"},{"line_number":111,"context_line":"            \u0027projects\u0027: [project.copy()],"},{"line_number":112,"context_line":"            \u0027domain\u0027: self.domain_mock,"},{"line_number":113,"context_line":"            \u0027projects_json\u0027: [project_json.copy()],"},{"line_number":114,"context_line":"        }"},{"line_number":115,"context_line":"        result \u003d self.rule_processor_schema_2_0.extract_projects("},{"line_number":116,"context_line":"            identity_values"}],"source_content_type":"text/x-python","patch_set":11,"id":"59d69670_db4217f2","line":113,"updated":"2025-10-30 11:27:28.000000000","message":"here we see that projects_json is actually an array of objects and not the string how it was declared above.","commit_id":"f1822c1b30acbef803d82445f9cd55f0afe39fdd"},{"author":{"_account_id":28356,"name":"Rafael Weingartner","email":"rafael@apache.org","username":"rafaelweingartner"},"change_message_id":"b5d9e81eead6ada6eabd8aa026192030e0cbe262","unresolved":false,"context_lines":[{"line_number":110,"context_line":"        identity_values \u003d {"},{"line_number":111,"context_line":"            \u0027projects\u0027: [project.copy()],"},{"line_number":112,"context_line":"            \u0027domain\u0027: self.domain_mock,"},{"line_number":113,"context_line":"            \u0027projects_json\u0027: [project_json.copy()],"},{"line_number":114,"context_line":"        }"},{"line_number":115,"context_line":"        result \u003d self.rule_processor_schema_2_0.extract_projects("},{"line_number":116,"context_line":"            identity_values"}],"source_content_type":"text/x-python","patch_set":11,"id":"e85af058_8297c3b6","line":113,"in_reply_to":"59d69670_db4217f2","updated":"2025-12-10 13:17:09.000000000","message":"This is one test. I will add another one to use it as string. This is the part of the tests where the schema version is validated/tested.","commit_id":"f1822c1b30acbef803d82445f9cd55f0afe39fdd"}]}
