)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":16137,"name":"Tobias Urdin","email":"tobias.urdin@binero.com","username":"tobasco"},"change_message_id":"81b3f396df3b5757590f1c4049a03dc0b78f8bdf","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"22e36638_f19f59c1","updated":"2024-08-14 13:15:24.000000000","message":"Any feedback on this with above explanation?","commit_id":"2e03e5d06f736238c7956849e8461ee12d7f4dc2"},{"author":{"_account_id":8648,"name":"Radomir Dopieralski","email":"openstack@dopieralski.pl","username":"thesheep"},"change_message_id":"ebf74f51eb6c8ddefa06568269321b0be24bb020","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"930e64e1_6fdee027","updated":"2024-05-08 10:04:01.000000000","message":"Why do we need this?","commit_id":"2e03e5d06f736238c7956849e8461ee12d7f4dc2"},{"author":{"_account_id":16137,"name":"Tobias Urdin","email":"tobias.urdin@binero.com","username":"tobasco"},"change_message_id":"cceb7802baf5e122fb9d42a77e9ca752a9d77306","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"958ab298_ccff1c93","updated":"2024-05-13 07:24:27.000000000","message":"recheck unrelated volume attachment selenium failures","commit_id":"2e03e5d06f736238c7956849e8461ee12d7f4dc2"},{"author":{"_account_id":16137,"name":"Tobias Urdin","email":"tobias.urdin@binero.com","username":"tobasco"},"change_message_id":"ab5f32f624bee091a810202dfe8f449a53bb8cdb","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"886f159a_bb76b886","updated":"2024-05-08 09:47:07.000000000","message":"tested working on zed","commit_id":"2e03e5d06f736238c7956849e8461ee12d7f4dc2"},{"author":{"_account_id":16137,"name":"Tobias Urdin","email":"tobias.urdin@binero.com","username":"tobasco"},"change_message_id":"21e87f824c744dee689ea840b545a01ef8244f30","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"b44388f0_038ab142","in_reply_to":"0ea39227_a62f6ad3","updated":"2024-05-19 20:24:16.000000000","message":"I was mentioning why we need this \"feature\", not related to Horizon per see, I was motivating why I think this should be added to Horizon.\n\nIf we have Keystone projects that is named for example `123456` and we don\u0027t have access to lookup the project ID we can still generate a link like https://horizon/auth/switch/123456 and display that in third-party systems (for example a inventory/DCIM system).","commit_id":"2e03e5d06f736238c7956849e8461ee12d7f4dc2"},{"author":{"_account_id":16137,"name":"Tobias Urdin","email":"tobias.urdin@binero.com","username":"tobasco"},"change_message_id":"6d9297457a1d46be22858091604de97f88da38a3","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"8fee9eb2_ade807fb","in_reply_to":"5054014d_99bcb486","updated":"2025-03-19 07:41:17.000000000","message":"If someone can maliciously name their project that means they are either system scope admin or manager in a domain which means you probably have bigger issues than being able to create projects with malicious names.\n\nEven then I don\u0027t see how any of that is a vulnerability, can you explain? It\u0027s not like Horizon has any kind of admin credentials that magically creates tokens for you, it\u0027s still your unscoped token used to switch to another project by name instead of UUID.","commit_id":"2e03e5d06f736238c7956849e8461ee12d7f4dc2"},{"author":{"_account_id":8648,"name":"Radomir Dopieralski","email":"openstack@dopieralski.pl","username":"thesheep"},"change_message_id":"84e27468ffde066658326d89d73593946654a083","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"0ea39227_a62f6ad3","in_reply_to":"8d7324f6_6e1ce8bc","updated":"2024-05-13 09:56:18.000000000","message":"I don\u0027t understand. Can you point me exactly to the code where this is used in horizon?","commit_id":"2e03e5d06f736238c7956849e8461ee12d7f4dc2"},{"author":{"_account_id":16137,"name":"Tobias Urdin","email":"tobias.urdin@binero.com","username":"tobasco"},"change_message_id":"987039ee0a837ad3744c9f6f09f7d2c96de3f2af","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"8d7324f6_6e1ce8bc","in_reply_to":"930e64e1_6fdee027","updated":"2024-05-13 07:22:14.000000000","message":"We use deterministic naming (customer numbers) as project names which means we can generate the link based on that.\n\nThis makes it easier since we don\u0027t need any kind of API access to the third-party system (looking up the project UUID) or any manual step requiring to enter the project UUID on the customer card.\n\nIt\u0027s also very convenient as it\u0027s faster to swap the number in the URL than using Horizon when listing 1000+ projects.","commit_id":"2e03e5d06f736238c7956849e8461ee12d7f4dc2"},{"author":{"_account_id":8648,"name":"Radomir Dopieralski","email":"openstack@dopieralski.pl","username":"thesheep"},"change_message_id":"4bb6d219837efa6ae01923bfd3725c77180602ad","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"5054014d_99bcb486","in_reply_to":"b44388f0_038ab142","updated":"2025-03-18 14:30:54.000000000","message":"What happens when someone maliciously names their project with the UUID of another project?","commit_id":"2e03e5d06f736238c7956849e8461ee12d7f4dc2"},{"author":{"_account_id":8648,"name":"Radomir Dopieralski","email":"openstack@dopieralski.pl","username":"thesheep"},"change_message_id":"b09b3501cf0133721e03f90de85d2dd3e856be2e","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"4bc69245_4eda2cee","updated":"2025-03-18 14:34:13.000000000","message":"Horizon is not an API, and its URLs are an internal implementation detail, not supposed to be used by other software. This change introduces a dangerous ambiguity that could be used to deny access to a project for another user.","commit_id":"261dc4ebdf3640afff82e33966a815ecabc62262"},{"author":{"_account_id":16137,"name":"Tobias Urdin","email":"tobias.urdin@binero.com","username":"tobasco"},"change_message_id":"6d9297457a1d46be22858091604de97f88da38a3","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"452e3653_0e040f2b","in_reply_to":"4bc69245_4eda2cee","updated":"2025-03-19 07:41:17.000000000","message":"I buy this sentiment and if the consensus is that it\u0027s to be treated as an implementation detail and we can never introduce functionality in the URL that helps operators and cloud users be more productive then that\u0027s fine.\n\nBut please elaborate on how it\u0027s dangerous and what I am missing because I don\u0027t understand.","commit_id":"261dc4ebdf3640afff82e33966a815ecabc62262"},{"author":{"_account_id":37598,"name":"Ivan Anfimov","display_name":"Ivan Anfimov","email":"lazekteam@gmail.com","username":"anfimovir"},"change_message_id":"0932eba87601e61cd34d82a4712363e0b6b3551d","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":4,"id":"4a6494ca_d5ec13b0","updated":"2025-09-12 14:54:47.000000000","message":"@tobias.urdin@binero.com hello, please add release note.","commit_id":"e1e985e0dc972af106bc6bf10c48fad85cbf8a31"},{"author":{"_account_id":8648,"name":"Radomir Dopieralski","email":"openstack@dopieralski.pl","username":"thesheep"},"change_message_id":"de9b121f642f1fe90951833548c15293fe6627fb","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"b0bad16f_3a6c91dd","updated":"2025-09-12 15:28:47.000000000","message":"Looks good now, just a small nitpick with how inheritance works with super(), and a release note about the new endpoint would be nice.","commit_id":"e1e985e0dc972af106bc6bf10c48fad85cbf8a31"},{"author":{"_account_id":37598,"name":"Ivan Anfimov","display_name":"Ivan Anfimov","email":"lazekteam@gmail.com","username":"anfimovir"},"change_message_id":"3cdd3a33461a05e76758c820a3682a42f75d80e0","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"0df150b9_8b30cfb8","in_reply_to":"4a6494ca_d5ec13b0","updated":"2025-09-12 16:53:34.000000000","message":"@tobias.urdin@binero.com thank you.","commit_id":"e1e985e0dc972af106bc6bf10c48fad85cbf8a31"},{"author":{"_account_id":37598,"name":"Ivan Anfimov","display_name":"Ivan Anfimov","email":"lazekteam@gmail.com","username":"anfimovir"},"change_message_id":"c3b7296c7cf33148ee50c1dd349e259dcd99aef1","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":5,"id":"8dc02853_ebbdbf6d","updated":"2025-09-12 16:54:45.000000000","message":"LGTM","commit_id":"c16437f330175f3a089b2b43f31abe1a3c06cbec"}],"openstack_auth/tests/unit/test_auth.py":[{"author":{"_account_id":35133,"name":"Jan Jasek","email":"jjasek@redhat.com","username":"janjasek"},"change_message_id":"2254dddf1f3b19b6115daa38a85a04125c264040","unresolved":true,"context_lines":[{"line_number":1310,"context_line":"            response \u003d self.client.post(url, form_data)"},{"line_number":1311,"context_line":"            self.assertRedirects(response, settings.LOGIN_REDIRECT_URL)"},{"line_number":1312,"context_line":""},{"line_number":1313,"context_line":"            url \u003d reverse(\u0027switch_project_id\u0027, args\u003d[project.id])"},{"line_number":1314,"context_line":""},{"line_number":1315,"context_line":"            scoped._project[\u0027id\u0027] \u003d self.data.project_two.id"},{"line_number":1316,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"a9424d2d_02825ac5","line":1313,"range":{"start_line":1313,"start_character":12,"end_line":1313,"end_character":65},"updated":"2026-04-29 10:23:19.000000000","message":"Hello @tobias.urdin@binero.com, thank you for your patch!\nI have a few points that I would like to clarify.\n\nThe existing test was updated to cover ```switch_project_id``` but there is no new test for ```switch_project_name``` endpoint. The ```ProjectSwitchByNameView``` introduces additional logic for extracting the domain from current token which is not covered by existing test. Could you please add also a test for switching project by name?","commit_id":"208d5380767df768ad474ae91463e8652e28f7b4"}],"openstack_auth/views.py":[{"author":{"_account_id":8648,"name":"Radomir Dopieralski","email":"openstack@dopieralski.pl","username":"thesheep"},"change_message_id":"92f65fd3f92f7d48c4e52a63e36332ef8557e911","unresolved":true,"context_lines":[{"line_number":283,"context_line":"    # another token. Always use the unscoped token for requesting a"},{"line_number":284,"context_line":"    # scoped token."},{"line_number":285,"context_line":"    unscoped_token \u003d request.user.unscoped_token"},{"line_number":286,"context_line":"    if uuidutils.is_uuid_like(tenant_id):"},{"line_number":287,"context_line":"        auth \u003d utils.get_token_auth_plugin(auth_url\u003dendpoint,"},{"line_number":288,"context_line":"                                           token\u003dunscoped_token,"},{"line_number":289,"context_line":"                                           project_id\u003dtenant_id)"}],"source_content_type":"text/x-python","patch_set":3,"id":"f56022aa_c5261f53","line":286,"updated":"2025-09-12 09:35:10.000000000","message":"I think this is still a problem. Just because something looks like uuid, doesn\u0027t mean it is an uuid.\n\nI wonder if you could move the code from this function into a separate function, and have two endpoints, one for switching by name and a separate one for switching by uuid, both calling that function? This is still completely unnecessary for Horizon, but at least it wouldn\u0027t introduce ambiguity.","commit_id":"261dc4ebdf3640afff82e33966a815ecabc62262"},{"author":{"_account_id":8648,"name":"Radomir Dopieralski","email":"openstack@dopieralski.pl","username":"thesheep"},"change_message_id":"de9b121f642f1fe90951833548c15293fe6627fb","unresolved":false,"context_lines":[{"line_number":283,"context_line":"    # another token. Always use the unscoped token for requesting a"},{"line_number":284,"context_line":"    # scoped token."},{"line_number":285,"context_line":"    unscoped_token \u003d request.user.unscoped_token"},{"line_number":286,"context_line":"    if uuidutils.is_uuid_like(tenant_id):"},{"line_number":287,"context_line":"        auth \u003d utils.get_token_auth_plugin(auth_url\u003dendpoint,"},{"line_number":288,"context_line":"                                           token\u003dunscoped_token,"},{"line_number":289,"context_line":"                                           project_id\u003dtenant_id)"}],"source_content_type":"text/x-python","patch_set":3,"id":"68380360_ef4c385b","line":286,"in_reply_to":"f56022aa_c5261f53","updated":"2025-09-12 15:28:47.000000000","message":"Done","commit_id":"261dc4ebdf3640afff82e33966a815ecabc62262"},{"author":{"_account_id":8648,"name":"Radomir Dopieralski","email":"openstack@dopieralski.pl","username":"thesheep"},"change_message_id":"de9b121f642f1fe90951833548c15293fe6627fb","unresolved":true,"context_lines":[{"line_number":274,"context_line":"class ProjectSwitchView(View):"},{"line_number":275,"context_line":"    def _get_token_auth_plugin(self, request):"},{"line_number":276,"context_line":"        \"\"\"This need to be implemented by the view.\"\"\""},{"line_number":277,"context_line":"        raise NotImplementedError"},{"line_number":278,"context_line":""},{"line_number":279,"context_line":"    def get(self, request, project):"},{"line_number":280,"context_line":"        LOG.debug(\u0027Switching to project %s for user \"%s\".\u0027,"}],"source_content_type":"text/x-python","patch_set":4,"id":"d0c4a3fc_238b25ab","line":277,"updated":"2025-09-12 15:28:47.000000000","message":"please don\u0027t raise an exception here, just leave an empty method, so that super() can be used","commit_id":"e1e985e0dc972af106bc6bf10c48fad85cbf8a31"},{"author":{"_account_id":37598,"name":"Ivan Anfimov","display_name":"Ivan Anfimov","email":"lazekteam@gmail.com","username":"anfimovir"},"change_message_id":"c3b7296c7cf33148ee50c1dd349e259dcd99aef1","unresolved":false,"context_lines":[{"line_number":274,"context_line":"class ProjectSwitchView(View):"},{"line_number":275,"context_line":"    def _get_token_auth_plugin(self, request):"},{"line_number":276,"context_line":"        \"\"\"This need to be implemented by the view.\"\"\""},{"line_number":277,"context_line":"        raise NotImplementedError"},{"line_number":278,"context_line":""},{"line_number":279,"context_line":"    def get(self, request, project):"},{"line_number":280,"context_line":"        LOG.debug(\u0027Switching to project %s for user \"%s\".\u0027,"}],"source_content_type":"text/x-python","patch_set":4,"id":"e2595833_966cc913","line":277,"in_reply_to":"d0c4a3fc_238b25ab","updated":"2025-09-12 16:54:45.000000000","message":"Done","commit_id":"e1e985e0dc972af106bc6bf10c48fad85cbf8a31"},{"author":{"_account_id":35133,"name":"Jan Jasek","email":"jjasek@redhat.com","username":"janjasek"},"change_message_id":"2254dddf1f3b19b6115daa38a85a04125c264040","unresolved":true,"context_lines":[{"line_number":272,"context_line":""},{"line_number":273,"context_line":""},{"line_number":274,"context_line":"class ProjectSwitchView(View):"},{"line_number":275,"context_line":"    def _get_token_auth_plugin_kwargs(self, request):"},{"line_number":276,"context_line":"        \"\"\"This need to be implemented by the view.\"\"\""},{"line_number":277,"context_line":"        return {}"},{"line_number":278,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"99fefa77_b2a8ce74","line":275,"range":{"start_line":275,"start_character":37,"end_line":275,"end_character":52},"updated":"2026-04-29 10:23:19.000000000","message":"```_get_token_auth_plugin_kwargs``` is defined with parameters ```(self, request)``` but in the ```get()``` on the line 296 it is called with parameters ```(request, project)```. And also both subclasses define it with project parameters.\nI understand that it will not cause any issue in current implementation as you never initiate ```ProjectSwitchView``` directly. But it is a little bit confusing and in case of reusing the first class, it is necessary to override ```_get_token_auth_plugin_kwargs``` to avoid ```TypeError```. Is there any specific reason why it is implemented like that, that I am missing? If not, could you please update the base class to ```(self, request, project)```?","commit_id":"208d5380767df768ad474ae91463e8652e28f7b4"}],"releasenotes/notes/auth-switch-project-name-d45ec94e3ded8a7f.yaml":[{"author":{"_account_id":35133,"name":"Jan Jasek","email":"jjasek@redhat.com","username":"janjasek"},"change_message_id":"2254dddf1f3b19b6115daa38a85a04125c264040","unresolved":true,"context_lines":[{"line_number":2,"context_line":"features:"},{"line_number":3,"context_line":"  - |"},{"line_number":4,"context_line":"    Added a new URL endpoint ``/auth/switch_name/\u003cproject-name\u003e`` to Horizon that can"},{"line_number":5,"context_line":"    be used to switch to another project by name. This is the same functionality as"},{"line_number":6,"context_line":"    is already provided by the ``/auth/switch/\u003cproject-id\u003e`` endpoint that only works"},{"line_number":7,"context_line":"    with an project ID (UUID)."}],"source_content_type":"text/x-yaml","patch_set":6,"id":"27901c91_db14119a","line":5,"range":{"start_line":5,"start_character":50,"end_line":5,"end_character":80},"updated":"2026-04-29 10:23:19.000000000","message":"As I am not super familiar with Keystone so I am not certainly sure here but I would probably argue - is not switching by project-name (in current implementation) limited by Domain? As the UUIDs are globally unique across the entire OpenStack compared to project names that are only unique within a specific domain? Which is the reason why ```ProjectSwitchByNameView``` uses ```domain \u003d request.user.token.project[\u0027domain_id\u0027]```.\nBased on the implementation I guess that you work with single domain deployment so this implementation is not a limitation for you but if I am right, it would be good to mention it here that this is not the same functionality as project-id and it has limitations.","commit_id":"208d5380767df768ad474ae91463e8652e28f7b4"}]}
