)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":27621,"name":"Vishakha Agarwal","email":"agarwalvishakha18@gmail.com","username":"Vishakha"},"change_message_id":"0d1d38933103cde456b36358d44dfb920ffad203","unresolved":false,"context_lines":[{"line_number":12,"context_line":"and associated along with the user."},{"line_number":13,"context_line":""},{"line_number":14,"context_line":"Change-Id: I6db03af81099a7509635881f05adf5a7257466a7"},{"line_number":15,"context_line":"Implements: bp support-federated-attr"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":7,"id":"7faddb67_d83a3696","line":15,"range":{"start_line":15,"start_character":0,"end_line":15,"end_character":12},"updated":"2019-08-21 13:46:42.000000000","message":"Can tag bug-id here too?","commit_id":"bff6817c64917610863b6cbed1f22ce8e6bce6ba"}],"keystone/identity/core.py":[{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"639616f1aff4379c97f1861b4a65634936a93dc9","unresolved":false,"context_lines":[{"line_number":927,"context_line":"    def _validate_federated_objects(self, fed_obj_list):"},{"line_number":928,"context_line":"        # Validate that the ipd and protocols exist"},{"line_number":929,"context_line":"        for fed_obj in fed_obj_list:"},{"line_number":930,"context_line":"            self.federation_api.get_idp(fed_obj[\u0027idp_id\u0027])"},{"line_number":931,"context_line":"            for protocols in fed_obj[\u0027protocols\u0027]:"},{"line_number":932,"context_line":"                self.federation_api.get_protocol(fed_obj[\u0027idp_id\u0027],"},{"line_number":933,"context_line":"                                                 protocols[\u0027protocol_id\u0027])"}],"source_content_type":"text/x-python","patch_set":8,"id":"1fa4df85_008d2930","line":930,"range":{"start_line":930,"start_character":12,"end_line":930,"end_character":58},"updated":"2020-03-18 23:45:22.000000000","message":"This needs to be handled. If this fails, it will return a Not Found to the user, but we actually need it to return a Bad Request https://github.com/openstack/api-sig/blob/master/guidelines/http/response-codes.rst#failure-code-clarifications","commit_id":"228294d9b1039fb123fd7abfd1129268b401e4ee"},{"author":{"_account_id":16465,"name":"Kristi Nikolla","email":"knikolla@bu.edu","username":"knikolla"},"change_message_id":"c566349f9800930e5f4a2be5cbc19eec6df4e6cf","unresolved":false,"context_lines":[{"line_number":927,"context_line":"    def _validate_federated_objects(self, fed_obj_list):"},{"line_number":928,"context_line":"        # Validate that the ipd and protocols exist"},{"line_number":929,"context_line":"        for fed_obj in fed_obj_list:"},{"line_number":930,"context_line":"            self.federation_api.get_idp(fed_obj[\u0027idp_id\u0027])"},{"line_number":931,"context_line":"            for protocols in fed_obj[\u0027protocols\u0027]:"},{"line_number":932,"context_line":"                self.federation_api.get_protocol(fed_obj[\u0027idp_id\u0027],"},{"line_number":933,"context_line":"                                                 protocols[\u0027protocol_id\u0027])"}],"source_content_type":"text/x-python","patch_set":8,"id":"1fa4df85_00c1a9e4","line":930,"range":{"start_line":930,"start_character":12,"end_line":930,"end_character":58},"in_reply_to":"1fa4df85_008d2930","updated":"2020-03-19 00:19:02.000000000","message":"Good catch! Same thing for the get_protocol down below.","commit_id":"228294d9b1039fb123fd7abfd1129268b401e4ee"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"e1db3bf33c186fd1eebaacfce9651b83abf661f0","unresolved":false,"context_lines":[{"line_number":948,"context_line":"    def _create_user_with_federated_objects(self, user, driver):"},{"line_number":949,"context_line":"        # If the user did not pass a federated object along inside the user"},{"line_number":950,"context_line":"        # object then we simply create the user as normal."},{"line_number":951,"context_line":"        if not user.get(\u0027federated\u0027):"},{"line_number":952,"context_line":"            if \u0027federated\u0027 in user:"},{"line_number":953,"context_line":"                del user[\u0027federated\u0027]"},{"line_number":954,"context_line":"            user \u003d driver.create_user(user[\u0027id\u0027], user)"},{"line_number":955,"context_line":"            return user"}],"source_content_type":"text/x-python","patch_set":8,"id":"1fa4df85_6ddc1674","line":952,"range":{"start_line":951,"start_character":8,"end_line":952,"end_character":35},"updated":"2020-03-18 21:57:52.000000000","message":"aren\u0027t these contrary?","commit_id":"228294d9b1039fb123fd7abfd1129268b401e4ee"},{"author":{"_account_id":16465,"name":"Kristi Nikolla","email":"knikolla@bu.edu","username":"knikolla"},"change_message_id":"c566349f9800930e5f4a2be5cbc19eec6df4e6cf","unresolved":false,"context_lines":[{"line_number":948,"context_line":"    def _create_user_with_federated_objects(self, user, driver):"},{"line_number":949,"context_line":"        # If the user did not pass a federated object along inside the user"},{"line_number":950,"context_line":"        # object then we simply create the user as normal."},{"line_number":951,"context_line":"        if not user.get(\u0027federated\u0027):"},{"line_number":952,"context_line":"            if \u0027federated\u0027 in user:"},{"line_number":953,"context_line":"                del user[\u0027federated\u0027]"},{"line_number":954,"context_line":"            user \u003d driver.create_user(user[\u0027id\u0027], user)"},{"line_number":955,"context_line":"            return user"}],"source_content_type":"text/x-python","patch_set":8,"id":"1fa4df85_80acb935","line":952,"range":{"start_line":951,"start_character":8,"end_line":952,"end_character":35},"in_reply_to":"1fa4df85_6ddc1674","updated":"2020-03-19 00:19:02.000000000","message":"Indeed, that second check seems unnecessary. Will remove.","commit_id":"228294d9b1039fb123fd7abfd1129268b401e4ee"},{"author":{"_account_id":16465,"name":"Kristi Nikolla","email":"knikolla@bu.edu","username":"knikolla"},"change_message_id":"1c5e1e1d17011d9b2b86156e0455badfe8e14d2b","unresolved":false,"context_lines":[{"line_number":948,"context_line":"    def _create_user_with_federated_objects(self, user, driver):"},{"line_number":949,"context_line":"        # If the user did not pass a federated object along inside the user"},{"line_number":950,"context_line":"        # object then we simply create the user as normal."},{"line_number":951,"context_line":"        if not user.get(\u0027federated\u0027):"},{"line_number":952,"context_line":"            if \u0027federated\u0027 in user:"},{"line_number":953,"context_line":"                del user[\u0027federated\u0027]"},{"line_number":954,"context_line":"            user \u003d driver.create_user(user[\u0027id\u0027], user)"},{"line_number":955,"context_line":"            return user"}],"source_content_type":"text/x-python","patch_set":8,"id":"df33271e_7ef66365","line":952,"range":{"start_line":951,"start_character":8,"end_line":952,"end_character":35},"in_reply_to":"1fa4df85_6ddc1674","updated":"2020-03-31 15:59:38.000000000","message":"On deeper look, it seems fine. First conditional checks for null, empty or nonexistent. Second conditional cleans it up if existent.","commit_id":"228294d9b1039fb123fd7abfd1129268b401e4ee"},{"author":{"_account_id":16465,"name":"Kristi Nikolla","email":"knikolla@bu.edu","username":"knikolla"},"change_message_id":"cf2e8120f65115b46d766fde718d96665ee9d973","unresolved":false,"context_lines":[{"line_number":948,"context_line":"    def _create_user_with_federated_objects(self, user, driver):"},{"line_number":949,"context_line":"        # If the user did not pass a federated object along inside the user"},{"line_number":950,"context_line":"        # object then we simply create the user as normal."},{"line_number":951,"context_line":"        if not user.get(\u0027federated\u0027):"},{"line_number":952,"context_line":"            if \u0027federated\u0027 in user:"},{"line_number":953,"context_line":"                del user[\u0027federated\u0027]"},{"line_number":954,"context_line":"            user \u003d driver.create_user(user[\u0027id\u0027], user)"},{"line_number":955,"context_line":"            return user"}],"source_content_type":"text/x-python","patch_set":8,"id":"df33271e_faa3969c","line":952,"range":{"start_line":951,"start_character":8,"end_line":952,"end_character":35},"in_reply_to":"df33271e_27a68754","updated":"2020-03-31 22:36:06.000000000","message":"In case that\u0027s what the API user does when calling the create_user. The schema allows an array, so it would probably allow an empty one to pass through.","commit_id":"228294d9b1039fb123fd7abfd1129268b401e4ee"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"85c5f2b1003c0f499d7c58d2420a5e83f34af6d1","unresolved":false,"context_lines":[{"line_number":948,"context_line":"    def _create_user_with_federated_objects(self, user, driver):"},{"line_number":949,"context_line":"        # If the user did not pass a federated object along inside the user"},{"line_number":950,"context_line":"        # object then we simply create the user as normal."},{"line_number":951,"context_line":"        if not user.get(\u0027federated\u0027):"},{"line_number":952,"context_line":"            if \u0027federated\u0027 in user:"},{"line_number":953,"context_line":"                del user[\u0027federated\u0027]"},{"line_number":954,"context_line":"            user \u003d driver.create_user(user[\u0027id\u0027], user)"},{"line_number":955,"context_line":"            return user"}],"source_content_type":"text/x-python","patch_set":8,"id":"df33271e_27a68754","line":952,"range":{"start_line":951,"start_character":8,"end_line":952,"end_character":35},"in_reply_to":"df33271e_7ef66365","updated":"2020-03-31 22:00:35.000000000","message":"Why would it be existent but empty?","commit_id":"228294d9b1039fb123fd7abfd1129268b401e4ee"}],"keystone/identity/schema.py":[{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"639616f1aff4379c97f1861b4a65634936a93dc9","unresolved":false,"context_lines":[{"line_number":34,"context_line":"    \u0027domain_id\u0027: parameter_types.id_string,"},{"line_number":35,"context_line":"    \u0027enabled\u0027: parameter_types.boolean,"},{"line_number":36,"context_line":"    \u0027federated\u0027: {"},{"line_number":37,"context_line":"        \u0027type\u0027: \u0027array\u0027,"},{"line_number":38,"context_line":"        \u0027items\u0027:"},{"line_number":39,"context_line":"            {"},{"line_number":40,"context_line":"                \u0027type\u0027: \u0027object\u0027,"}],"source_content_type":"text/x-python","patch_set":8,"id":"1fa4df85_20ace58a","line":37,"range":{"start_line":37,"start_character":8,"end_line":37,"end_character":23},"updated":"2020-03-18 23:45:22.000000000","message":"Is this so a local user can be mapped to multiple IdPs?","commit_id":"228294d9b1039fb123fd7abfd1129268b401e4ee"},{"author":{"_account_id":16465,"name":"Kristi Nikolla","email":"knikolla@bu.edu","username":"knikolla"},"change_message_id":"c566349f9800930e5f4a2be5cbc19eec6df4e6cf","unresolved":false,"context_lines":[{"line_number":34,"context_line":"    \u0027domain_id\u0027: parameter_types.id_string,"},{"line_number":35,"context_line":"    \u0027enabled\u0027: parameter_types.boolean,"},{"line_number":36,"context_line":"    \u0027federated\u0027: {"},{"line_number":37,"context_line":"        \u0027type\u0027: \u0027array\u0027,"},{"line_number":38,"context_line":"        \u0027items\u0027:"},{"line_number":39,"context_line":"            {"},{"line_number":40,"context_line":"                \u0027type\u0027: \u0027object\u0027,"}],"source_content_type":"text/x-python","patch_set":8,"id":"1fa4df85_20fdc539","line":37,"range":{"start_line":37,"start_character":8,"end_line":37,"end_character":23},"in_reply_to":"1fa4df85_20ace58a","updated":"2020-03-19 00:19:02.000000000","message":"Yes. That was the general direction that Ron and Richard were taking users at the time of the writing of this code.","commit_id":"228294d9b1039fb123fd7abfd1129268b401e4ee"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"639616f1aff4379c97f1861b4a65634936a93dc9","unresolved":false,"context_lines":[{"line_number":47,"context_line":"                                \u0027type\u0027: \u0027object\u0027,"},{"line_number":48,"context_line":"                                \u0027properties\u0027: {"},{"line_number":49,"context_line":"                                    \u0027protocol_id\u0027: {\u0027type\u0027: \u0027string\u0027},"},{"line_number":50,"context_line":"                                    \u0027unique_id\u0027: {\u0027type\u0027: \u0027string\u0027}"},{"line_number":51,"context_line":"                                },"},{"line_number":52,"context_line":"                                \u0027required\u0027: [\u0027protocol_id\u0027, \u0027unique_id\u0027]"},{"line_number":53,"context_line":"                            },"}],"source_content_type":"text/x-python","patch_set":8,"id":"1fa4df85_60a2dd9c","line":50,"range":{"start_line":50,"start_character":36,"end_line":50,"end_character":67},"updated":"2020-03-18 23:45:22.000000000","message":"What does this mean? What is the need for it? Why is it part of the list of protocols?","commit_id":"228294d9b1039fb123fd7abfd1129268b401e4ee"},{"author":{"_account_id":16465,"name":"Kristi Nikolla","email":"knikolla@bu.edu","username":"knikolla"},"change_message_id":"c566349f9800930e5f4a2be5cbc19eec6df4e6cf","unresolved":false,"context_lines":[{"line_number":47,"context_line":"                                \u0027type\u0027: \u0027object\u0027,"},{"line_number":48,"context_line":"                                \u0027properties\u0027: {"},{"line_number":49,"context_line":"                                    \u0027protocol_id\u0027: {\u0027type\u0027: \u0027string\u0027},"},{"line_number":50,"context_line":"                                    \u0027unique_id\u0027: {\u0027type\u0027: \u0027string\u0027}"},{"line_number":51,"context_line":"                                },"},{"line_number":52,"context_line":"                                \u0027required\u0027: [\u0027protocol_id\u0027, \u0027unique_id\u0027]"},{"line_number":53,"context_line":"                            },"}],"source_content_type":"text/x-python","patch_set":8,"id":"1fa4df85_c0a15148","line":50,"range":{"start_line":50,"start_character":36,"end_line":50,"end_character":67},"in_reply_to":"1fa4df85_60a2dd9c","updated":"2020-03-19 00:19:02.000000000","message":"An idp can have multiple protocols. The unique_id passed down may be different for each protocol and idp. This is to allow multiple federated identities for each user.","commit_id":"228294d9b1039fb123fd7abfd1129268b401e4ee"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"85c5f2b1003c0f499d7c58d2420a5e83f34af6d1","unresolved":false,"context_lines":[{"line_number":47,"context_line":"                                \u0027type\u0027: \u0027object\u0027,"},{"line_number":48,"context_line":"                                \u0027properties\u0027: {"},{"line_number":49,"context_line":"                                    \u0027protocol_id\u0027: {\u0027type\u0027: \u0027string\u0027},"},{"line_number":50,"context_line":"                                    \u0027unique_id\u0027: {\u0027type\u0027: \u0027string\u0027}"},{"line_number":51,"context_line":"                                },"},{"line_number":52,"context_line":"                                \u0027required\u0027: [\u0027protocol_id\u0027, \u0027unique_id\u0027]"},{"line_number":53,"context_line":"                            },"}],"source_content_type":"text/x-python","patch_set":8,"id":"df33271e_477e2baf","line":50,"range":{"start_line":50,"start_character":36,"end_line":50,"end_character":67},"in_reply_to":"1fa4df85_c0a15148","updated":"2020-03-31 22:00:35.000000000","message":"I\u0027m still unclear where this comes from, is this just made up by the admin? Is it generated by keystone? How is the admin supposed to know what to put here?","commit_id":"228294d9b1039fb123fd7abfd1129268b401e4ee"},{"author":{"_account_id":16465,"name":"Kristi Nikolla","email":"knikolla@bu.edu","username":"knikolla"},"change_message_id":"cf2e8120f65115b46d766fde718d96665ee9d973","unresolved":false,"context_lines":[{"line_number":47,"context_line":"                                \u0027type\u0027: \u0027object\u0027,"},{"line_number":48,"context_line":"                                \u0027properties\u0027: {"},{"line_number":49,"context_line":"                                    \u0027protocol_id\u0027: {\u0027type\u0027: \u0027string\u0027},"},{"line_number":50,"context_line":"                                    \u0027unique_id\u0027: {\u0027type\u0027: \u0027string\u0027}"},{"line_number":51,"context_line":"                                },"},{"line_number":52,"context_line":"                                \u0027required\u0027: [\u0027protocol_id\u0027, \u0027unique_id\u0027]"},{"line_number":53,"context_line":"                            },"}],"source_content_type":"text/x-python","patch_set":8,"id":"df33271e_5aa722be","line":50,"range":{"start_line":50,"start_character":36,"end_line":50,"end_character":67},"in_reply_to":"df33271e_477e2baf","updated":"2020-03-31 22:36:06.000000000","message":"It\u0027s the unique identifier sent by the identity provider in the assertion. In SAML, it would be the NameID, in OIDC it would be the username. When a user logs in via federation, keystone stores this in https://opendev.org/openstack/keystone/src/branch/master/keystone/identity/backends/sql_model.py#L339","commit_id":"228294d9b1039fb123fd7abfd1129268b401e4ee"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"1f470b733910dbe3b57de513fb1380a323931179","unresolved":false,"context_lines":[{"line_number":47,"context_line":"                                \u0027type\u0027: \u0027object\u0027,"},{"line_number":48,"context_line":"                                \u0027properties\u0027: {"},{"line_number":49,"context_line":"                                    \u0027protocol_id\u0027: {\u0027type\u0027: \u0027string\u0027},"},{"line_number":50,"context_line":"                                    \u0027unique_id\u0027: {\u0027type\u0027: \u0027string\u0027}"},{"line_number":51,"context_line":"                                },"},{"line_number":52,"context_line":"                                \u0027required\u0027: [\u0027protocol_id\u0027, \u0027unique_id\u0027]"},{"line_number":53,"context_line":"                            },"}],"source_content_type":"text/x-python","patch_set":8,"id":"df33271e_7d294088","line":50,"range":{"start_line":50,"start_character":36,"end_line":50,"end_character":67},"in_reply_to":"df33271e_5aa722be","updated":"2020-03-31 23:12:06.000000000","message":"ohhhh gotcha thanks","commit_id":"228294d9b1039fb123fd7abfd1129268b401e4ee"}],"keystone/tests/unit/test_shadow_users.py":[{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"15a846152f6ece63991a307a5f68b0f0bbc0a904","unresolved":false,"context_lines":[{"line_number":13,"context_line":"import uuid"},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"from keystone import exception"},{"line_number":16,"context_line":"from keystone.common import provider_api"},{"line_number":17,"context_line":"from keystone.tests import unit"},{"line_number":18,"context_line":"from keystone.tests.unit import default_fixtures"},{"line_number":19,"context_line":"from keystone.tests.unit.identity.shadow_users import test_backend"}],"source_content_type":"text/x-python","patch_set":10,"id":"df33271e_1837bdb2","line":16,"updated":"2020-04-08 02:43:23.000000000","message":"pep8: H306  imports not in alphabetical order (keystone.exception, keystone.common.provider_api)","commit_id":"62655dfbbb77722cc5ec73e1f74d1309d5389380"}]}
