)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"89062064c151893347bfd719a4ca3fbf428cfc4e","unresolved":false,"context_lines":[{"line_number":4,"context_line":"Commit:     Lance Bragstad \u003clbragstad@gmail.com\u003e"},{"line_number":5,"context_line":"CommitDate: 2017-01-12 19:45:42 +0000"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Implement shadow mapping"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Provide a way to provision projects and assignments when a federated"},{"line_number":10,"context_line":"user authenticates for the first time for an unscoped token."}],"source_content_type":"text/x-gerrit-commit-message","patch_set":11,"id":"7a3c09a3_e76afc19","line":7,"range":{"start_line":7,"start_character":10,"end_line":7,"end_character":24},"updated":"2017-01-13 15:37:25.000000000","message":"https://en.wikipedia.org/wiki/Shadow_mapping :)","commit_id":"1323e6de47b4f723b81733d4c2a35c94cd0b8c52"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"ee939b456d6aeae9e18501b333aa262287062a7d","unresolved":false,"context_lines":[{"line_number":4,"context_line":"Commit:     Lance Bragstad \u003clbragstad@gmail.com\u003e"},{"line_number":5,"context_line":"CommitDate: 2017-01-12 19:45:42 +0000"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Implement shadow mapping"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Provide a way to provision projects and assignments when a federated"},{"line_number":10,"context_line":"user authenticates for the first time for an unscoped token."}],"source_content_type":"text/x-gerrit-commit-message","patch_set":11,"id":"7a3c09a3_56325d11","line":7,"in_reply_to":"7a3c09a3_e76afc19","updated":"2017-01-16 15:23:41.000000000","message":"Aha - we could think about changing the name. Maybe something like \"Federated Auto-provisioning\" instead?","commit_id":"1323e6de47b4f723b81733d4c2a35c94cd0b8c52"}],"keystone/auth/plugins/mapped.py":[{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"cb5fa356c96ee6eb89f9b176c5cc866e82dec12b","unresolved":false,"context_lines":[{"line_number":125,"context_line":"        for shadow_project in shadow_projects:"},{"line_number":126,"context_line":"            # This assumes that every shadow mapping that contains a project"},{"line_number":127,"context_line":"            # also contains roles within that project."},{"line_number":128,"context_line":"            shadow_roles \u003d shadow_project[\u0027roles\u0027]"},{"line_number":129,"context_line":"            for shadow_role in shadow_roles:"},{"line_number":130,"context_line":"                if shadow_role[\u0027name\u0027] not in existing_roles.keys():"},{"line_number":131,"context_line":"                    msg \u003d _(\u0027Role %s does not exist.\u0027) % role[\u0027name\u0027]"}],"source_content_type":"text/x-python","patch_set":1,"id":"ba5201f7_e2d99658","line":128,"updated":"2017-01-05 13:54:00.000000000","message":"(nit) I don\u0027t think I\u0027d give this a name and instead use \"shadow_project[\u0027roles\u0027]\" directly in the \u0027for\u0027 statement.","commit_id":"c302751936f369aad732be91386aa0fbc51780f0"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"4c29a3eb2981dc1614e705e4c0fb1c29487f6112","unresolved":false,"context_lines":[{"line_number":125,"context_line":"        for shadow_project in shadow_projects:"},{"line_number":126,"context_line":"            # This assumes that every shadow mapping that contains a project"},{"line_number":127,"context_line":"            # also contains roles within that project."},{"line_number":128,"context_line":"            shadow_roles \u003d shadow_project[\u0027roles\u0027]"},{"line_number":129,"context_line":"            for shadow_role in shadow_roles:"},{"line_number":130,"context_line":"                if shadow_role[\u0027name\u0027] not in existing_roles.keys():"},{"line_number":131,"context_line":"                    msg \u003d _(\u0027Role %s does not exist.\u0027) % role[\u0027name\u0027]"}],"source_content_type":"text/x-python","patch_set":1,"id":"ba5201f7_e8d6c5ef","line":128,"in_reply_to":"ba5201f7_e2d99658","updated":"2017-01-05 21:45:39.000000000","message":"Done","commit_id":"c302751936f369aad732be91386aa0fbc51780f0"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"cb5fa356c96ee6eb89f9b176c5cc866e82dec12b","unresolved":false,"context_lines":[{"line_number":127,"context_line":"            # also contains roles within that project."},{"line_number":128,"context_line":"            shadow_roles \u003d shadow_project[\u0027roles\u0027]"},{"line_number":129,"context_line":"            for shadow_role in shadow_roles:"},{"line_number":130,"context_line":"                if shadow_role[\u0027name\u0027] not in existing_roles.keys():"},{"line_number":131,"context_line":"                    msg \u003d _(\u0027Role %s does not exist.\u0027) % role[\u0027name\u0027]"},{"line_number":132,"context_line":"                    raise exception.RoleNotFound(msg)"},{"line_number":133,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"ba5201f7_e2c0b652","line":130,"updated":"2017-01-05 13:54:00.000000000","message":"Remove \u0027.keys()\u0027. This will use a keys iterator internally so it\u0027s cleaner looking and slightly faster on Py2.","commit_id":"c302751936f369aad732be91386aa0fbc51780f0"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"4c29a3eb2981dc1614e705e4c0fb1c29487f6112","unresolved":false,"context_lines":[{"line_number":127,"context_line":"            # also contains roles within that project."},{"line_number":128,"context_line":"            shadow_roles \u003d shadow_project[\u0027roles\u0027]"},{"line_number":129,"context_line":"            for shadow_role in shadow_roles:"},{"line_number":130,"context_line":"                if shadow_role[\u0027name\u0027] not in existing_roles.keys():"},{"line_number":131,"context_line":"                    msg \u003d _(\u0027Role %s does not exist.\u0027) % role[\u0027name\u0027]"},{"line_number":132,"context_line":"                    raise exception.RoleNotFound(msg)"},{"line_number":133,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"ba5201f7_48fc3172","line":130,"in_reply_to":"ba5201f7_e2c0b652","updated":"2017-01-05 21:45:39.000000000","message":"Done","commit_id":"c302751936f369aad732be91386aa0fbc51780f0"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"559cea426d6f4ceb8f2c89436ea90d6e17dfeef5","unresolved":false,"context_lines":[{"line_number":124,"context_line":""},{"line_number":125,"context_line":"        for shadow_project in shadow_projects:"},{"line_number":126,"context_line":"            # This assumes that every shadow mapping that contains a project"},{"line_number":127,"context_line":"            # also contains roles within that project."},{"line_number":128,"context_line":"            for shadow_role in shadow_project[\u0027roles\u0027]:"},{"line_number":129,"context_line":"                if shadow_role[\u0027name\u0027] not in existing_roles:"},{"line_number":130,"context_line":"                    msg \u003d _(\u0027Role %s does not exist.\u0027) % role[\u0027name\u0027]"}],"source_content_type":"text/x-python","patch_set":5,"id":"ba5201f7_57a35e9e","line":127,"updated":"2017-01-10 14:26:02.000000000","message":"what happens if it does not ? KeyError ? we should validate the mapping somehow before this.\n\nAlso, the spec says they\u0027d created: \"If any of those projects or roles do not exist, they must be created by Keystone automatically.\"\n\nhttps://specs.openstack.org/openstack/keystone-specs/specs/keystone/ocata/shadow-mapping.html","commit_id":"d7c241d27b6355f701141fb4c2872f3abeadef25"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"a4ea2bf8b36f527f66b56d52fc62c224b0c3e418","unresolved":false,"context_lines":[{"line_number":124,"context_line":""},{"line_number":125,"context_line":"        for shadow_project in shadow_projects:"},{"line_number":126,"context_line":"            # This assumes that every shadow mapping that contains a project"},{"line_number":127,"context_line":"            # also contains roles within that project."},{"line_number":128,"context_line":"            for shadow_role in shadow_project[\u0027roles\u0027]:"},{"line_number":129,"context_line":"                if shadow_role[\u0027name\u0027] not in existing_roles:"},{"line_number":130,"context_line":"                    msg \u003d _(\u0027Role %s does not exist.\u0027) % role[\u0027name\u0027]"}],"source_content_type":"text/x-python","patch_set":5,"id":"ba5201f7_907cd7b6","line":127,"in_reply_to":"ba5201f7_57a35e9e","updated":"2017-01-10 23:24:39.000000000","message":"Yep - i\u0027ve add some validation logic to the mapping schema when we create and update mappings. That should be in the latest patch set.","commit_id":"d7c241d27b6355f701141fb4c2872f3abeadef25"},{"author":{"_account_id":11022,"name":"Rodrigo Duarte Sousa","email":"rodrigodsousa@gmail.com","username":"rodrigods"},"change_message_id":"bf348de83b84daad9f3c8ec252d64d9046dc6d3d","unresolved":false,"context_lines":[{"line_number":112,"context_line":"                          assignment_api, role_api):"},{"line_number":113,"context_line":""},{"line_number":114,"context_line":"    def shadow_mapping(assignment_api, resource_api, federation_api, role_api,"},{"line_number":115,"context_line":"                       mapped_properties, identity_provider_domain_id, user):"},{"line_number":116,"context_line":""},{"line_number":117,"context_line":"        # Validate that the roles in the shadow mapping actually exist. If"},{"line_number":118,"context_line":"        # they don\u0027t we should bail early before creating anything."}],"source_content_type":"text/x-python","patch_set":7,"id":"ba5201f7_4507fa80","line":115,"range":{"start_line":115,"start_character":23,"end_line":115,"end_character":40},"updated":"2017-01-11 11:56:24.000000000","message":"you only pass mapped_properties to get the shadow_projects, since you already check if \"projects\" is a key of mapped_properties at line 208, I would pass them directly.","commit_id":"69cba05587abf23b6d48d351c29cdc2db5c0d654"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"47ad6893f659fd1907a27cd272e53089dc19ede5","unresolved":false,"context_lines":[{"line_number":112,"context_line":"                          assignment_api, role_api):"},{"line_number":113,"context_line":""},{"line_number":114,"context_line":"    def shadow_mapping(assignment_api, resource_api, federation_api, role_api,"},{"line_number":115,"context_line":"                       mapped_properties, identity_provider_domain_id, user):"},{"line_number":116,"context_line":""},{"line_number":117,"context_line":"        # Validate that the roles in the shadow mapping actually exist. If"},{"line_number":118,"context_line":"        # they don\u0027t we should bail early before creating anything."}],"source_content_type":"text/x-python","patch_set":7,"id":"ba5201f7_2229018a","line":115,"in_reply_to":"ba5201f7_4507fa80","updated":"2017-01-11 15:57:47.000000000","message":"True, I was following the convention (if we could call it that) used by some of the other methods in this module, but passing only shadow_projects makes sense.","commit_id":"69cba05587abf23b6d48d351c29cdc2db5c0d654"},{"author":{"_account_id":11022,"name":"Rodrigo Duarte Sousa","email":"rodrigodsousa@gmail.com","username":"rodrigods"},"change_message_id":"bf348de83b84daad9f3c8ec252d64d9046dc6d3d","unresolved":false,"context_lines":[{"line_number":117,"context_line":"        # Validate that the roles in the shadow mapping actually exist. If"},{"line_number":118,"context_line":"        # they don\u0027t we should bail early before creating anything."},{"line_number":119,"context_line":"        shadow_projects \u003d mapped_properties[\u0027projects\u0027]"},{"line_number":120,"context_line":"        roles \u003d role_api.list_roles()"},{"line_number":121,"context_line":"        existing_roles \u003d {}"},{"line_number":122,"context_line":"        for role in roles:"},{"line_number":123,"context_line":"            existing_roles[role[\u0027name\u0027]] \u003d role"}],"source_content_type":"text/x-python","patch_set":7,"id":"ba5201f7_6544fe73","line":120,"range":{"start_line":120,"start_character":8,"end_line":120,"end_character":37},"updated":"2017-01-11 11:56:24.000000000","message":"maybe add a comment for the reasoning for listing all roles for later lookup instead of getting them in line 128? shadow_project[\u0027roles\u0027] can be empty, so no API call to the roles API would be necessary.","commit_id":"69cba05587abf23b6d48d351c29cdc2db5c0d654"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"47ad6893f659fd1907a27cd272e53089dc19ede5","unresolved":false,"context_lines":[{"line_number":117,"context_line":"        # Validate that the roles in the shadow mapping actually exist. If"},{"line_number":118,"context_line":"        # they don\u0027t we should bail early before creating anything."},{"line_number":119,"context_line":"        shadow_projects \u003d mapped_properties[\u0027projects\u0027]"},{"line_number":120,"context_line":"        roles \u003d role_api.list_roles()"},{"line_number":121,"context_line":"        existing_roles \u003d {}"},{"line_number":122,"context_line":"        for role in roles:"},{"line_number":123,"context_line":"            existing_roles[role[\u0027name\u0027]] \u003d role"}],"source_content_type":"text/x-python","patch_set":7,"id":"ba5201f7_875e3f43","line":120,"in_reply_to":"ba5201f7_6544fe73","updated":"2017-01-11 15:57:47.000000000","message":"I added some bits to the mapping schema for JSON schema to check to make sure that roles are always populated in the event projects are in the mapping. I don\u0027t think we want roles to be empty when we have projects in the mapping. If this is the case (which I thought I covered) then I think we\u0027d need to revisit the tests to make sure that isn\u0027t happening.","commit_id":"69cba05587abf23b6d48d351c29cdc2db5c0d654"},{"author":{"_account_id":11022,"name":"Rodrigo Duarte Sousa","email":"rodrigodsousa@gmail.com","username":"rodrigods"},"change_message_id":"bf348de83b84daad9f3c8ec252d64d9046dc6d3d","unresolved":false,"context_lines":[{"line_number":150,"context_line":""},{"line_number":151,"context_line":"            shadow_roles \u003d shadow_project[\u0027roles\u0027]"},{"line_number":152,"context_line":"            for shadow_role in shadow_roles:"},{"line_number":153,"context_line":"                assignment_api.create_grant("},{"line_number":154,"context_line":"                    existing_roles[shadow_role[\u0027name\u0027]][\u0027id\u0027],"},{"line_number":155,"context_line":"                    user_id\u003duser[\u0027id\u0027],"},{"line_number":156,"context_line":"                    project_id\u003dproject[\u0027id\u0027]"}],"source_content_type":"text/x-python","patch_set":7,"id":"ba5201f7_70411a0b","line":153,"range":{"start_line":153,"start_character":16,"end_line":153,"end_character":44},"updated":"2017-01-11 11:56:24.000000000","message":"this can blow up at [1], would be nice to test this case.\n\n[1] https://github.com/openstack/keystone/blob/master/keystone/assignment/core.py#L310","commit_id":"69cba05587abf23b6d48d351c29cdc2db5c0d654"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"47ad6893f659fd1907a27cd272e53089dc19ede5","unresolved":false,"context_lines":[{"line_number":150,"context_line":""},{"line_number":151,"context_line":"            shadow_roles \u003d shadow_project[\u0027roles\u0027]"},{"line_number":152,"context_line":"            for shadow_role in shadow_roles:"},{"line_number":153,"context_line":"                assignment_api.create_grant("},{"line_number":154,"context_line":"                    existing_roles[shadow_role[\u0027name\u0027]][\u0027id\u0027],"},{"line_number":155,"context_line":"                    user_id\u003duser[\u0027id\u0027],"},{"line_number":156,"context_line":"                    project_id\u003dproject[\u0027id\u0027]"}],"source_content_type":"text/x-python","patch_set":7,"id":"ba5201f7_22d3c160","line":153,"in_reply_to":"ba5201f7_70411a0b","updated":"2017-01-11 15:57:47.000000000","message":"Ah - this seems like it would be something to add to the validation pieces at the beginning of this method. That way if the role in a mapping belongs to a different domain than the identity provider, we can bail before we create anything.\n\nOn the other hand, emitting that kinda of error at authentication time might not help the user that much. If anything I would think we\u0027d want to have that kind of validation when the operator originally creates the mapping so that users don\u0027t have to deal with an exception they can\u0027t do anything about, that could be a future improvement though.","commit_id":"69cba05587abf23b6d48d351c29cdc2db5c0d654"},{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"55cad8cbf4ce9b588462e15fbff1785896b0784f","unresolved":false,"context_lines":[{"line_number":111,"context_line":"                          resource_api, federation_api, identity_api,"},{"line_number":112,"context_line":"                          assignment_api, role_api):"},{"line_number":113,"context_line":""},{"line_number":114,"context_line":"    def shadow_mapping(assignment_api, resource_api, federation_api, role_api,"},{"line_number":115,"context_line":"                       shadow_projects, idp_id, user):"},{"line_number":116,"context_line":"        idp_domain_id \u003d federation_api.get_idp(idp_id)[\u0027domain_id\u0027]"},{"line_number":117,"context_line":"        # Validate that the roles in the shadow mapping actually exist. If"}],"source_content_type":"text/x-python","patch_set":8,"id":"ba5201f7_43fa6b44","line":114,"range":{"start_line":114,"start_character":8,"end_line":114,"end_character":22},"updated":"2017-01-12 01:08:35.000000000","message":"Would prefer a more descriptive name, such as create_mapping_project_and_roles or something.","commit_id":"545f20444fdc1d35528dde06ffdf34c609187cf5"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"b36693b5fbb5eb04f5ed2975e8d23e6326a5dbbb","unresolved":false,"context_lines":[{"line_number":111,"context_line":"                          resource_api, federation_api, identity_api,"},{"line_number":112,"context_line":"                          assignment_api, role_api):"},{"line_number":113,"context_line":""},{"line_number":114,"context_line":"    def shadow_mapping(assignment_api, resource_api, federation_api, role_api,"},{"line_number":115,"context_line":"                       shadow_projects, idp_id, user):"},{"line_number":116,"context_line":"        idp_domain_id \u003d federation_api.get_idp(idp_id)[\u0027domain_id\u0027]"},{"line_number":117,"context_line":"        # Validate that the roles in the shadow mapping actually exist. If"}],"source_content_type":"text/x-python","patch_set":8,"id":"9a57fde8_477204e7","line":114,"in_reply_to":"9a57fde8_e2a5abb5","updated":"2017-01-12 15:12:35.000000000","message":"As I was writing this, I was really hoping this module had some sort of class structure and I\u0027m surprised that there isn\u0027t one. This seems to be one of the few places in keystone with this type of convention. I\u0027m all for suggestions on making this better!\n\nDavid, what exactly do you mean by not needing any _api arguments? Are you instead suggesting that we pull this utility outside of `handle_unscoped_tokens` and use dependencies to provide the required APIs?","commit_id":"545f20444fdc1d35528dde06ffdf34c609187cf5"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"ea5c240aff542d1f0c1579388854a1a684ab42bf","unresolved":false,"context_lines":[{"line_number":111,"context_line":"                          resource_api, federation_api, identity_api,"},{"line_number":112,"context_line":"                          assignment_api, role_api):"},{"line_number":113,"context_line":""},{"line_number":114,"context_line":"    def shadow_mapping(assignment_api, resource_api, federation_api, role_api,"},{"line_number":115,"context_line":"                       shadow_projects, idp_id, user):"},{"line_number":116,"context_line":"        idp_domain_id \u003d federation_api.get_idp(idp_id)[\u0027domain_id\u0027]"},{"line_number":117,"context_line":"        # Validate that the roles in the shadow mapping actually exist. If"}],"source_content_type":"text/x-python","patch_set":8,"id":"9a57fde8_1e13f15d","line":114,"range":{"start_line":114,"start_character":8,"end_line":114,"end_character":22},"in_reply_to":"ba5201f7_43fa6b44","updated":"2017-01-12 09:50:13.000000000","message":"++ yeah, this can be too shadowed","commit_id":"545f20444fdc1d35528dde06ffdf34c609187cf5"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"45664311e218158cc1f0dd67f170e54f05db4e4d","unresolved":false,"context_lines":[{"line_number":111,"context_line":"                          resource_api, federation_api, identity_api,"},{"line_number":112,"context_line":"                          assignment_api, role_api):"},{"line_number":113,"context_line":""},{"line_number":114,"context_line":"    def shadow_mapping(assignment_api, resource_api, federation_api, role_api,"},{"line_number":115,"context_line":"                       shadow_projects, idp_id, user):"},{"line_number":116,"context_line":"        idp_domain_id \u003d federation_api.get_idp(idp_id)[\u0027domain_id\u0027]"},{"line_number":117,"context_line":"        # Validate that the roles in the shadow mapping actually exist. If"}],"source_content_type":"text/x-python","patch_set":8,"id":"9a57fde8_e2a5abb5","line":114,"in_reply_to":"ba5201f7_43fa6b44","updated":"2017-01-12 13:32:19.000000000","message":"I agree. Having create in the name would be important. Also I wonder if this is too big to be nested. Although a nested function has access to the variables defined in the outer scope so you actually don\u0027t need to take any *_api arguments here.","commit_id":"545f20444fdc1d35528dde06ffdf34c609187cf5"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"45664311e218158cc1f0dd67f170e54f05db4e4d","unresolved":false,"context_lines":[{"line_number":119,"context_line":"        roles \u003d role_api.list_roles()"},{"line_number":120,"context_line":"        existing_roles \u003d {}"},{"line_number":121,"context_line":"        for role in roles:"},{"line_number":122,"context_line":"            existing_roles[role[\u0027name\u0027]] \u003d role"},{"line_number":123,"context_line":""},{"line_number":124,"context_line":"        for shadow_project in shadow_projects:"},{"line_number":125,"context_line":"            # This assumes that every shadow mapping that contains a project"}],"source_content_type":"text/x-python","patch_set":8,"id":"9a57fde8_82c4df40","line":122,"updated":"2017-01-12 13:32:19.000000000","message":"suggest: existing_roles \u003d {role[\u0027name\u0027]: role for role in role_api.list_roles()}","commit_id":"545f20444fdc1d35528dde06ffdf34c609187cf5"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"b36693b5fbb5eb04f5ed2975e8d23e6326a5dbbb","unresolved":false,"context_lines":[{"line_number":119,"context_line":"        roles \u003d role_api.list_roles()"},{"line_number":120,"context_line":"        existing_roles \u003d {}"},{"line_number":121,"context_line":"        for role in roles:"},{"line_number":122,"context_line":"            existing_roles[role[\u0027name\u0027]] \u003d role"},{"line_number":123,"context_line":""},{"line_number":124,"context_line":"        for shadow_project in shadow_projects:"},{"line_number":125,"context_line":"            # This assumes that every shadow mapping that contains a project"}],"source_content_type":"text/x-python","patch_set":8,"id":"9a57fde8_6add0d70","line":122,"in_reply_to":"9a57fde8_82c4df40","updated":"2017-01-12 15:12:35.000000000","message":"Done","commit_id":"545f20444fdc1d35528dde06ffdf34c609187cf5"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"45664311e218158cc1f0dd67f170e54f05db4e4d","unresolved":false,"context_lines":[{"line_number":122,"context_line":"            existing_roles[role[\u0027name\u0027]] \u003d role"},{"line_number":123,"context_line":""},{"line_number":124,"context_line":"        for shadow_project in shadow_projects:"},{"line_number":125,"context_line":"            # This assumes that every shadow mapping that contains a project"},{"line_number":126,"context_line":"            # also contains roles within that project."},{"line_number":127,"context_line":"            for shadow_role in shadow_project[\u0027roles\u0027]:"},{"line_number":128,"context_line":"                # The role in the projet mapping must exist in order for it to"}],"source_content_type":"text/x-python","patch_set":8,"id":"9a57fde8_21ab308b","line":125,"updated":"2017-01-12 13:32:19.000000000","message":"I think this comment isn\u0027t needed. The fact that you are just access roles mean you expect them to be there.","commit_id":"545f20444fdc1d35528dde06ffdf34c609187cf5"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"b36693b5fbb5eb04f5ed2975e8d23e6326a5dbbb","unresolved":false,"context_lines":[{"line_number":122,"context_line":"            existing_roles[role[\u0027name\u0027]] \u003d role"},{"line_number":123,"context_line":""},{"line_number":124,"context_line":"        for shadow_project in shadow_projects:"},{"line_number":125,"context_line":"            # This assumes that every shadow mapping that contains a project"},{"line_number":126,"context_line":"            # also contains roles within that project."},{"line_number":127,"context_line":"            for shadow_role in shadow_project[\u0027roles\u0027]:"},{"line_number":128,"context_line":"                # The role in the projet mapping must exist in order for it to"}],"source_content_type":"text/x-python","patch_set":8,"id":"9a57fde8_cabb590d","line":125,"in_reply_to":"9a57fde8_21ab308b","updated":"2017-01-12 15:12:35.000000000","message":"Done","commit_id":"545f20444fdc1d35528dde06ffdf34c609187cf5"},{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"55cad8cbf4ce9b588462e15fbff1785896b0784f","unresolved":false,"context_lines":[{"line_number":125,"context_line":"            # This assumes that every shadow mapping that contains a project"},{"line_number":126,"context_line":"            # also contains roles within that project."},{"line_number":127,"context_line":"            for shadow_role in shadow_project[\u0027roles\u0027]:"},{"line_number":128,"context_line":"                # The role in the projet mapping must exist in order for it to"},{"line_number":129,"context_line":"                # be useful."},{"line_number":130,"context_line":"                if shadow_role[\u0027name\u0027] not in existing_roles:"},{"line_number":131,"context_line":"                    msg \u003d _(\u0027Role %s does not exist.\u0027) % role[\u0027name\u0027]"}],"source_content_type":"text/x-python","patch_set":8,"id":"ba5201f7_e3143f4e","line":128,"range":{"start_line":128,"start_character":34,"end_line":128,"end_character":40},"updated":"2017-01-12 01:08:35.000000000","message":"nit: *project","commit_id":"545f20444fdc1d35528dde06ffdf34c609187cf5"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"b36693b5fbb5eb04f5ed2975e8d23e6326a5dbbb","unresolved":false,"context_lines":[{"line_number":125,"context_line":"            # This assumes that every shadow mapping that contains a project"},{"line_number":126,"context_line":"            # also contains roles within that project."},{"line_number":127,"context_line":"            for shadow_role in shadow_project[\u0027roles\u0027]:"},{"line_number":128,"context_line":"                # The role in the projet mapping must exist in order for it to"},{"line_number":129,"context_line":"                # be useful."},{"line_number":130,"context_line":"                if shadow_role[\u0027name\u0027] not in existing_roles:"},{"line_number":131,"context_line":"                    msg \u003d _(\u0027Role %s does not exist.\u0027) % role[\u0027name\u0027]"}],"source_content_type":"text/x-python","patch_set":8,"id":"9a57fde8_ca69998d","line":128,"in_reply_to":"ba5201f7_e3143f4e","updated":"2017-01-12 15:12:35.000000000","message":"Done","commit_id":"545f20444fdc1d35528dde06ffdf34c609187cf5"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"ea5c240aff542d1f0c1579388854a1a684ab42bf","unresolved":false,"context_lines":[{"line_number":127,"context_line":"            for shadow_role in shadow_project[\u0027roles\u0027]:"},{"line_number":128,"context_line":"                # The role in the projet mapping must exist in order for it to"},{"line_number":129,"context_line":"                # be useful."},{"line_number":130,"context_line":"                if shadow_role[\u0027name\u0027] not in existing_roles:"},{"line_number":131,"context_line":"                    msg \u003d _(\u0027Role %s does not exist.\u0027) % role[\u0027name\u0027]"},{"line_number":132,"context_line":"                    raise exception.RoleNotFound(msg)"},{"line_number":133,"context_line":"                role \u003d existing_roles[shadow_role[\u0027name\u0027]]"},{"line_number":134,"context_line":"                if (role[\u0027domain_id\u0027] is not None and"},{"line_number":135,"context_line":"                        role[\u0027domain_id\u0027] !\u003d idp_domain_id):"}],"source_content_type":"text/x-python","patch_set":8,"id":"9a57fde8_a3301209","line":132,"range":{"start_line":130,"start_character":16,"end_line":132,"end_character":53},"updated":"2017-01-12 09:50:13.000000000","message":"Spec says the roles would be created, likewise to the projects.\n\n\"If any of those projects or roles do not exist, they must be created by Keystone automatically.\"\n\nhttps://specs.openstack.org/openstack/keystone-specs/specs/keystone/ocata/shadow-mapping.html","commit_id":"545f20444fdc1d35528dde06ffdf34c609187cf5"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"b36693b5fbb5eb04f5ed2975e8d23e6326a5dbbb","unresolved":false,"context_lines":[{"line_number":129,"context_line":"                # be useful."},{"line_number":130,"context_line":"                if shadow_role[\u0027name\u0027] not in existing_roles:"},{"line_number":131,"context_line":"                    msg \u003d _(\u0027Role %s does not exist.\u0027) % role[\u0027name\u0027]"},{"line_number":132,"context_line":"                    raise exception.RoleNotFound(msg)"},{"line_number":133,"context_line":"                role \u003d existing_roles[shadow_role[\u0027name\u0027]]"},{"line_number":134,"context_line":"                if (role[\u0027domain_id\u0027] is not None and"},{"line_number":135,"context_line":"                        role[\u0027domain_id\u0027] !\u003d idp_domain_id):"}],"source_content_type":"text/x-python","patch_set":8,"id":"9a57fde8_4a404957","line":132,"in_reply_to":"9a57fde8_a3301209","updated":"2017-01-12 15:12:35.000000000","message":"I believe there was a discussion sometime before the implementation started happening to see if that was really something we wanted to do.\n\nI think the main point was that deployers would still have to make policy changes across their deployment in order for the role to be useful, and if they have to do that, it would just make sense for them to create the role, too. This is probably something they\u0027d work out using configuration management. This isn\u0027t the case with projects since we can get the domain ID that they should be in the from the identity provider (thanks to Ron!).\n\nI can propose a patch to amend the spec if everyone is on board with that limitation.","commit_id":"545f20444fdc1d35528dde06ffdf34c609187cf5"},{"author":{"_account_id":11022,"name":"Rodrigo Duarte Sousa","email":"rodrigodsousa@gmail.com","username":"rodrigods"},"change_message_id":"2309b31544f61ca9fa8c012d527ca0a8f92d4ddc","unresolved":false,"context_lines":[{"line_number":131,"context_line":"                    msg \u003d _(\u0027Role %s does not exist.\u0027) % role[\u0027name\u0027]"},{"line_number":132,"context_line":"                    raise exception.RoleNotFound(msg)"},{"line_number":133,"context_line":"                role \u003d existing_roles[shadow_role[\u0027name\u0027]]"},{"line_number":134,"context_line":"                if (role[\u0027domain_id\u0027] is not None and"},{"line_number":135,"context_line":"                        role[\u0027domain_id\u0027] !\u003d idp_domain_id):"},{"line_number":136,"context_line":"                    raise exception.InvalidDomainSpecificRole("},{"line_number":137,"context_line":"                        role_name\u003dshadow_role[\u0027name\u0027],"},{"line_number":138,"context_line":"                        identity_provider\u003didp_id"}],"source_content_type":"text/x-python","patch_set":8,"id":"ba5201f7_1b91bcf1","line":135,"range":{"start_line":134,"start_character":0,"end_line":135,"end_character":60},"updated":"2017-01-11 18:06:54.000000000","message":"another option would be to catch DomainSpecificRoleMismatch and line 161 and transform into InvalidDomainSpecificRole","commit_id":"545f20444fdc1d35528dde06ffdf34c609187cf5"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"a6d8c1868fc4c48c3876e7edb9404164ba96fff7","unresolved":false,"context_lines":[{"line_number":132,"context_line":"                    raise exception.RoleNotFound(msg)"},{"line_number":133,"context_line":"                role \u003d existing_roles[shadow_role[\u0027name\u0027]]"},{"line_number":134,"context_line":"                if (role[\u0027domain_id\u0027] is not None and"},{"line_number":135,"context_line":"                        role[\u0027domain_id\u0027] !\u003d idp_domain_id):"},{"line_number":136,"context_line":"                    raise exception.InvalidDomainSpecificRole("},{"line_number":137,"context_line":"                        role_name\u003dshadow_role[\u0027name\u0027],"},{"line_number":138,"context_line":"                        identity_provider\u003didp_id"}],"source_content_type":"text/x-python","patch_set":8,"id":"ba5201f7_923d8a91","line":135,"in_reply_to":"ba5201f7_1b91bcf1","updated":"2017-01-11 18:53:38.000000000","message":"True - that would work. The only downside would be that we would have already created the project. I opted to have it here so that if the domain_role is outside of the identity provider\u0027s domain, then we bail on everything, instead of creating a project with a role assignment that the user ultimately can\u0027t use.","commit_id":"545f20444fdc1d35528dde06ffdf34c609187cf5"},{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"55cad8cbf4ce9b588462e15fbff1785896b0784f","unresolved":false,"context_lines":[{"line_number":114,"context_line":"    def shadow_mapping(assignment_api, resource_api, federation_api, role_api,"},{"line_number":115,"context_line":"                       shadow_projects, idp_id, user):"},{"line_number":116,"context_line":"        idp_domain_id \u003d federation_api.get_idp(idp_id)[\u0027domain_id\u0027]"},{"line_number":117,"context_line":"        # Validate that the roles in the shadow mapping actually exist. If"},{"line_number":118,"context_line":"        # they don\u0027t we should bail early before creating anything."},{"line_number":119,"context_line":"        roles \u003d role_api.list_roles()"},{"line_number":120,"context_line":"        existing_roles \u003d {}"},{"line_number":121,"context_line":"        for role in roles:"},{"line_number":122,"context_line":"            existing_roles[role[\u0027name\u0027]] \u003d role"},{"line_number":123,"context_line":""},{"line_number":124,"context_line":"        for shadow_project in shadow_projects:"},{"line_number":125,"context_line":"            # This assumes that every shadow mapping that contains a project"},{"line_number":126,"context_line":"            # also contains roles within that project."},{"line_number":127,"context_line":"            for shadow_role in shadow_project[\u0027roles\u0027]:"},{"line_number":128,"context_line":"                # The role in the projet mapping must exist in order for it to"},{"line_number":129,"context_line":"                # be useful."},{"line_number":130,"context_line":"                if shadow_role[\u0027name\u0027] not in existing_roles:"},{"line_number":131,"context_line":"                    msg \u003d _(\u0027Role %s does not exist.\u0027) % role[\u0027name\u0027]"},{"line_number":132,"context_line":"                    raise exception.RoleNotFound(msg)"},{"line_number":133,"context_line":"                role \u003d existing_roles[shadow_role[\u0027name\u0027]]"},{"line_number":134,"context_line":"                if (role[\u0027domain_id\u0027] is not None and"},{"line_number":135,"context_line":"                        role[\u0027domain_id\u0027] !\u003d idp_domain_id):"},{"line_number":136,"context_line":"                    raise exception.InvalidDomainSpecificRole("},{"line_number":137,"context_line":"                        role_name\u003dshadow_role[\u0027name\u0027],"},{"line_number":138,"context_line":"                        identity_provider\u003didp_id"},{"line_number":139,"context_line":"                    )"},{"line_number":140,"context_line":""},{"line_number":141,"context_line":"        for shadow_project in shadow_projects:"},{"line_number":142,"context_line":"            try:"}],"source_content_type":"text/x-python","patch_set":8,"id":"ba5201f7_c3b3bb98","line":139,"range":{"start_line":117,"start_character":8,"end_line":139,"end_character":21},"updated":"2017-01-12 01:08:35.000000000","message":"Why not have a separate method to do this validation?","commit_id":"545f20444fdc1d35528dde06ffdf34c609187cf5"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"b36693b5fbb5eb04f5ed2975e8d23e6326a5dbbb","unresolved":false,"context_lines":[{"line_number":136,"context_line":"                    raise exception.InvalidDomainSpecificRole("},{"line_number":137,"context_line":"                        role_name\u003dshadow_role[\u0027name\u0027],"},{"line_number":138,"context_line":"                        identity_provider\u003didp_id"},{"line_number":139,"context_line":"                    )"},{"line_number":140,"context_line":""},{"line_number":141,"context_line":"        for shadow_project in shadow_projects:"},{"line_number":142,"context_line":"            try:"}],"source_content_type":"text/x-python","patch_set":8,"id":"9a57fde8_d5b93aee","line":139,"in_reply_to":"ba5201f7_c3b3bb98","updated":"2017-01-12 15:12:35.000000000","message":"Done","commit_id":"545f20444fdc1d35528dde06ffdf34c609187cf5"},{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"55cad8cbf4ce9b588462e15fbff1785896b0784f","unresolved":false,"context_lines":[{"line_number":159,"context_line":"            shadow_roles \u003d shadow_project[\u0027roles\u0027]"},{"line_number":160,"context_line":"            for shadow_role in shadow_roles:"},{"line_number":161,"context_line":"                assignment_api.create_grant("},{"line_number":162,"context_line":"                    existing_roles[shadow_role[\u0027name\u0027]][\u0027id\u0027],"},{"line_number":163,"context_line":"                    user_id\u003duser[\u0027id\u0027],"},{"line_number":164,"context_line":"                    project_id\u003dproject[\u0027id\u0027]"},{"line_number":165,"context_line":"                )"}],"source_content_type":"text/x-python","patch_set":8,"id":"ba5201f7_9e058812","line":162,"range":{"start_line":162,"start_character":20,"end_line":162,"end_character":61},"updated":"2017-01-12 01:08:35.000000000","message":"confused by this, but it\u0027s late in the day :)","commit_id":"545f20444fdc1d35528dde06ffdf34c609187cf5"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"b36693b5fbb5eb04f5ed2975e8d23e6326a5dbbb","unresolved":false,"context_lines":[{"line_number":159,"context_line":"            shadow_roles \u003d shadow_project[\u0027roles\u0027]"},{"line_number":160,"context_line":"            for shadow_role in shadow_roles:"},{"line_number":161,"context_line":"                assignment_api.create_grant("},{"line_number":162,"context_line":"                    existing_roles[shadow_role[\u0027name\u0027]][\u0027id\u0027],"},{"line_number":163,"context_line":"                    user_id\u003duser[\u0027id\u0027],"},{"line_number":164,"context_line":"                    project_id\u003dproject[\u0027id\u0027]"},{"line_number":165,"context_line":"                )"}],"source_content_type":"text/x-python","patch_set":8,"id":"9a57fde8_350e0635","line":162,"in_reply_to":"ba5201f7_9e058812","updated":"2017-01-12 15:12:35.000000000","message":"I could pull this out and give it a reasonable name if that helps.","commit_id":"545f20444fdc1d35528dde06ffdf34c609187cf5"},{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"55cad8cbf4ce9b588462e15fbff1785896b0784f","unresolved":false,"context_lines":[{"line_number":214,"context_line":"                                                      display_name)"},{"line_number":215,"context_line":""},{"line_number":216,"context_line":"            if \u0027projects\u0027 in mapped_properties:"},{"line_number":217,"context_line":"                shadow_mapping("},{"line_number":218,"context_line":"                    assignment_api,"},{"line_number":219,"context_line":"                    resource_api,"},{"line_number":220,"context_line":"                    federation_api,"}],"source_content_type":"text/x-python","patch_set":8,"id":"ba5201f7_1e127857","line":217,"range":{"start_line":217,"start_character":16,"end_line":217,"end_character":30},"updated":"2017-01-12 01:08:35.000000000","message":"assign_user_mapped_project() maybe...","commit_id":"545f20444fdc1d35528dde06ffdf34c609187cf5"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"b36693b5fbb5eb04f5ed2975e8d23e6326a5dbbb","unresolved":false,"context_lines":[{"line_number":214,"context_line":"                                                      display_name)"},{"line_number":215,"context_line":""},{"line_number":216,"context_line":"            if \u0027projects\u0027 in mapped_properties:"},{"line_number":217,"context_line":"                shadow_mapping("},{"line_number":218,"context_line":"                    assignment_api,"},{"line_number":219,"context_line":"                    resource_api,"},{"line_number":220,"context_line":"                    federation_api,"}],"source_content_type":"text/x-python","patch_set":8,"id":"9a57fde8_55ce2a84","line":217,"in_reply_to":"ba5201f7_1e127857","updated":"2017-01-12 15:12:35.000000000","message":"Done","commit_id":"545f20444fdc1d35528dde06ffdf34c609187cf5"},{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"4c92e6ee3589132ecf018f0bc23aafe249b5c248","unresolved":false,"context_lines":[{"line_number":111,"context_line":"                          resource_api, federation_api, identity_api,"},{"line_number":112,"context_line":"                          assignment_api, role_api):"},{"line_number":113,"context_line":""},{"line_number":114,"context_line":"    def validate_shadow_mapping(shadow_projects, idp_id, federation_api,"},{"line_number":115,"context_line":"                                role_api):"},{"line_number":116,"context_line":"        idp_domain_id \u003d federation_api.get_idp(idp_id)[\u0027domain_id\u0027]"},{"line_number":117,"context_line":"        # Validate that the roles in the shadow mapping actually exist. If"}],"source_content_type":"text/x-python","patch_set":10,"id":"9a57fde8_59ec9cc7","line":114,"range":{"start_line":114,"start_character":8,"end_line":114,"end_character":31},"updated":"2017-01-12 18:05:07.000000000","message":"++","commit_id":"73e00996188c8ae3ce2707c1789ec0cf5c98e2eb"},{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"4c92e6ee3589132ecf018f0bc23aafe249b5c248","unresolved":false,"context_lines":[{"line_number":116,"context_line":"        idp_domain_id \u003d federation_api.get_idp(idp_id)[\u0027domain_id\u0027]"},{"line_number":117,"context_line":"        # Validate that the roles in the shadow mapping actually exist. If"},{"line_number":118,"context_line":"        # they don\u0027t we should bail early before creating anything."},{"line_number":119,"context_line":"        existing_roles \u003d {role[\u0027name\u0027]: role for role in role_api.list_roles()}"},{"line_number":120,"context_line":""},{"line_number":121,"context_line":"        for shadow_project in shadow_projects:"},{"line_number":122,"context_line":"            for shadow_role in shadow_project[\u0027roles\u0027]:"}],"source_content_type":"text/x-python","patch_set":10,"id":"9a57fde8_94f6cbd5","line":119,"range":{"start_line":119,"start_character":26,"end_line":119,"end_character":38},"updated":"2017-01-12 18:05:07.000000000","message":"I assume role names are unique...","commit_id":"73e00996188c8ae3ce2707c1789ec0cf5c98e2eb"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"386fc2a6287d7340429fa823d31ff8a02a70d3e5","unresolved":false,"context_lines":[{"line_number":116,"context_line":"        idp_domain_id \u003d federation_api.get_idp(idp_id)[\u0027domain_id\u0027]"},{"line_number":117,"context_line":"        # Validate that the roles in the shadow mapping actually exist. If"},{"line_number":118,"context_line":"        # they don\u0027t we should bail early before creating anything."},{"line_number":119,"context_line":"        existing_roles \u003d {role[\u0027name\u0027]: role for role in role_api.list_roles()}"},{"line_number":120,"context_line":""},{"line_number":121,"context_line":"        for shadow_project in shadow_projects:"},{"line_number":122,"context_line":"            for shadow_role in shadow_project[\u0027roles\u0027]:"}],"source_content_type":"text/x-python","patch_set":10,"id":"9a57fde8_2ee94b1b","line":119,"in_reply_to":"9a57fde8_94f6cbd5","updated":"2017-01-12 19:34:02.000000000","message":"yep - they should be within a domain","commit_id":"73e00996188c8ae3ce2707c1789ec0cf5c98e2eb"},{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"4c92e6ee3589132ecf018f0bc23aafe249b5c248","unresolved":false,"context_lines":[{"line_number":136,"context_line":"    def create_projects_from_mapping(assignment_api, resource_api,"},{"line_number":137,"context_line":"                                     federation_api, role_api,"},{"line_number":138,"context_line":"                                     shadow_projects, idp_id, user):"},{"line_number":139,"context_line":"        idp_domain_id \u003d federation_api.get_idp(idp_id)[\u0027domain_id\u0027]"},{"line_number":140,"context_line":"        existing_roles \u003d {role[\u0027name\u0027]: role for role in role_api.list_roles()}"},{"line_number":141,"context_line":"        for shadow_project in shadow_projects:"},{"line_number":142,"context_line":"            try:"},{"line_number":143,"context_line":"                # Check and see if the project already exists and if it"}],"source_content_type":"text/x-python","patch_set":10,"id":"9a57fde8_54b9c3e8","line":140,"range":{"start_line":139,"start_character":8,"end_line":140,"end_character":79},"updated":"2017-01-12 18:05:07.000000000","message":"nit: you\u0027re calling these in both the validate and create methods, you could call them once and pass them in the method parameters.","commit_id":"73e00996188c8ae3ce2707c1789ec0cf5c98e2eb"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"386fc2a6287d7340429fa823d31ff8a02a70d3e5","unresolved":false,"context_lines":[{"line_number":137,"context_line":"                                     federation_api, role_api,"},{"line_number":138,"context_line":"                                     shadow_projects, idp_id, user):"},{"line_number":139,"context_line":"        idp_domain_id \u003d federation_api.get_idp(idp_id)[\u0027domain_id\u0027]"},{"line_number":140,"context_line":"        existing_roles \u003d {role[\u0027name\u0027]: role for role in role_api.list_roles()}"},{"line_number":141,"context_line":"        for shadow_project in shadow_projects:"},{"line_number":142,"context_line":"            try:"},{"line_number":143,"context_line":"                # Check and see if the project already exists and if it"}],"source_content_type":"text/x-python","patch_set":10,"id":"9a57fde8_ceda7f78","line":140,"in_reply_to":"9a57fde8_54b9c3e8","updated":"2017-01-12 19:34:02.000000000","message":"++","commit_id":"73e00996188c8ae3ce2707c1789ec0cf5c98e2eb"},{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"4c92e6ee3589132ecf018f0bc23aafe249b5c248","unresolved":false,"context_lines":[{"line_number":218,"context_line":"                # then we need to make sure we validate all pieces of the"},{"line_number":219,"context_line":"                # mapping and what it\u0027s saying to create. If there is something"},{"line_number":220,"context_line":"                # wrong with how the mapping is, we should bail early before we"},{"line_number":221,"context_line":"                # create anything. If we create things then validate, we have"},{"line_number":222,"context_line":"                # to be able to go back and clean things up in the event"},{"line_number":223,"context_line":"                # something is wrong. Let\u0027s only create things if we are"},{"line_number":224,"context_line":"                # absolutely certain we can or should."},{"line_number":225,"context_line":"                validate_shadow_mapping("},{"line_number":226,"context_line":"                    mapped_properties[\u0027projects\u0027],"},{"line_number":227,"context_line":"                    identity_provider,"}],"source_content_type":"text/x-python","patch_set":10,"id":"9a57fde8_14bbbbc5","line":224,"range":{"start_line":221,"start_character":35,"end_line":224,"end_character":54},"updated":"2017-01-12 18:05:07.000000000","message":"nit: I don\u0027t think you need these last 2 sentences.","commit_id":"73e00996188c8ae3ce2707c1789ec0cf5c98e2eb"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"386fc2a6287d7340429fa823d31ff8a02a70d3e5","unresolved":false,"context_lines":[{"line_number":221,"context_line":"                # create anything. If we create things then validate, we have"},{"line_number":222,"context_line":"                # to be able to go back and clean things up in the event"},{"line_number":223,"context_line":"                # something is wrong. Let\u0027s only create things if we are"},{"line_number":224,"context_line":"                # absolutely certain we can or should."},{"line_number":225,"context_line":"                validate_shadow_mapping("},{"line_number":226,"context_line":"                    mapped_properties[\u0027projects\u0027],"},{"line_number":227,"context_line":"                    identity_provider,"}],"source_content_type":"text/x-python","patch_set":10,"id":"9a57fde8_f4be32fe","line":224,"in_reply_to":"9a57fde8_14bbbbc5","updated":"2017-01-12 19:34:02.000000000","message":"Done","commit_id":"73e00996188c8ae3ce2707c1789ec0cf5c98e2eb"},{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"89062064c151893347bfd719a4ca3fbf428cfc4e","unresolved":false,"context_lines":[{"line_number":209,"context_line":"                                                      display_name)"},{"line_number":210,"context_line":""},{"line_number":211,"context_line":"            if \u0027projects\u0027 in mapped_properties:"},{"line_number":212,"context_line":"                idp_domain_id \u003d federation_api.get_idp("},{"line_number":213,"context_line":"                    identity_provider"},{"line_number":214,"context_line":"                )[\u0027domain_id\u0027]"},{"line_number":215,"context_line":"                existing_roles \u003d {"},{"line_number":216,"context_line":"                    role[\u0027name\u0027]: role for role in role_api.list_roles()"},{"line_number":217,"context_line":"                }"},{"line_number":218,"context_line":"                # NOTE(lbragstad): If we are dealing with a shadow mapping,"},{"line_number":219,"context_line":"                # then we need to make sure we validate all pieces of the"},{"line_number":220,"context_line":"                # mapping and what it\u0027s saying to create. If there is something"}],"source_content_type":"text/x-python","patch_set":11,"id":"7a3c09a3_a73ab434","line":217,"range":{"start_line":212,"start_character":16,"end_line":217,"end_character":17},"updated":"2017-01-13 15:37:25.000000000","message":"++","commit_id":"1323e6de47b4f723b81733d4c2a35c94cd0b8c52"},{"author":{"_account_id":16465,"name":"Kristi Nikolla","email":"knikolla@bu.edu","username":"knikolla"},"change_message_id":"44d61f34b27ba0fa2b586531a5aad6a3c67dc954","unresolved":false,"context_lines":[{"line_number":225,"context_line":"                    existing_roles,"},{"line_number":226,"context_line":"                    idp_domain_id,"},{"line_number":227,"context_line":"                    identity_provider,"},{"line_number":228,"context_line":"                    federation_api,"},{"line_number":229,"context_line":"                    role_api"},{"line_number":230,"context_line":"                )"},{"line_number":231,"context_line":"                create_projects_from_mapping("},{"line_number":232,"context_line":"                    mapped_properties[\u0027projects\u0027],"}],"source_content_type":"text/x-python","patch_set":11,"id":"7a3c09a3_baa9d17d","line":229,"range":{"start_line":228,"start_character":0,"end_line":229,"end_character":28},"updated":"2017-01-14 14:43:38.000000000","message":"These appear unused.","commit_id":"1323e6de47b4f723b81733d4c2a35c94cd0b8c52"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"ee939b456d6aeae9e18501b333aa262287062a7d","unresolved":false,"context_lines":[{"line_number":226,"context_line":"                    idp_domain_id,"},{"line_number":227,"context_line":"                    identity_provider,"},{"line_number":228,"context_line":"                    federation_api,"},{"line_number":229,"context_line":"                    role_api"},{"line_number":230,"context_line":"                )"},{"line_number":231,"context_line":"                create_projects_from_mapping("},{"line_number":232,"context_line":"                    mapped_properties[\u0027projects\u0027],"}],"source_content_type":"text/x-python","patch_set":11,"id":"7a3c09a3_1869e38b","line":229,"in_reply_to":"7a3c09a3_baa9d17d","updated":"2017-01-16 15:23:41.000000000","message":"Done","commit_id":"1323e6de47b4f723b81733d4c2a35c94cd0b8c52"},{"author":{"_account_id":16465,"name":"Kristi Nikolla","email":"knikolla@bu.edu","username":"knikolla"},"change_message_id":"44d61f34b27ba0fa2b586531a5aad6a3c67dc954","unresolved":false,"context_lines":[{"line_number":235,"context_line":"                    user,"},{"line_number":236,"context_line":"                    assignment_api,"},{"line_number":237,"context_line":"                    resource_api,"},{"line_number":238,"context_line":"                    federation_api,"},{"line_number":239,"context_line":"                    role_api"},{"line_number":240,"context_line":"                )"},{"line_number":241,"context_line":""},{"line_number":242,"context_line":"            user_id \u003d user[\u0027id\u0027]"}],"source_content_type":"text/x-python","patch_set":11,"id":"7a3c09a3_1ab105e2","line":239,"range":{"start_line":238,"start_character":0,"end_line":239,"end_character":28},"updated":"2017-01-14 14:43:38.000000000","message":"These appear unused.","commit_id":"1323e6de47b4f723b81733d4c2a35c94cd0b8c52"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"ee939b456d6aeae9e18501b333aa262287062a7d","unresolved":false,"context_lines":[{"line_number":236,"context_line":"                    assignment_api,"},{"line_number":237,"context_line":"                    resource_api,"},{"line_number":238,"context_line":"                    federation_api,"},{"line_number":239,"context_line":"                    role_api"},{"line_number":240,"context_line":"                )"},{"line_number":241,"context_line":""},{"line_number":242,"context_line":"            user_id \u003d user[\u0027id\u0027]"}],"source_content_type":"text/x-python","patch_set":11,"id":"7a3c09a3_38069fce","line":239,"in_reply_to":"7a3c09a3_1ab105e2","updated":"2017-01-16 15:23:41.000000000","message":"Done","commit_id":"1323e6de47b4f723b81733d4c2a35c94cd0b8c52"},{"author":{"_account_id":16465,"name":"Kristi Nikolla","email":"knikolla@bu.edu","username":"knikolla"},"change_message_id":"ed7d299fd7f67318349a45e0b6bf8b77991a624e","unresolved":false,"context_lines":[{"line_number":225,"context_line":"                    existing_roles,"},{"line_number":226,"context_line":"                    idp_domain_id,"},{"line_number":227,"context_line":"                    identity_provider,"},{"line_number":228,"context_line":"                    federation_api"},{"line_number":229,"context_line":"                )"},{"line_number":230,"context_line":"                create_projects_from_mapping("},{"line_number":231,"context_line":"                    mapped_properties[\u0027projects\u0027],"}],"source_content_type":"text/x-python","patch_set":14,"id":"7a3c09a3_3c5ac42a","line":228,"updated":"2017-01-17 19:13:31.000000000","message":"federation_api is unused too.","commit_id":"69fefdaffba6060e9a054abf852c04d104189386"},{"author":{"_account_id":16465,"name":"Kristi Nikolla","email":"knikolla@bu.edu","username":"knikolla"},"change_message_id":"ed7d299fd7f67318349a45e0b6bf8b77991a624e","unresolved":false,"context_lines":[{"line_number":234,"context_line":"                    user,"},{"line_number":235,"context_line":"                    assignment_api,"},{"line_number":236,"context_line":"                    resource_api,"},{"line_number":237,"context_line":"                    federation_api"},{"line_number":238,"context_line":"                )"},{"line_number":239,"context_line":""},{"line_number":240,"context_line":"            user_id \u003d user[\u0027id\u0027]"}],"source_content_type":"text/x-python","patch_set":14,"id":"7a3c09a3_9c49f862","line":237,"updated":"2017-01-17 19:13:31.000000000","message":"federation_api is unused too.","commit_id":"69fefdaffba6060e9a054abf852c04d104189386"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"9c4342af51b64c3e1623b817508470590e6cab2a","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":15,"id":"5a3905b3_27f986c9","updated":"2017-01-19 05:16:48.000000000","message":"ugh we need to refactor this, badly","commit_id":"4ea0a20e02dad8816e49bf6b58b595db746ca385"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"9c4342af51b64c3e1623b817508470590e6cab2a","unresolved":false,"context_lines":[{"line_number":120,"context_line":"                # The role in the project mapping must exist in order for it to"},{"line_number":121,"context_line":"                # be useful."},{"line_number":122,"context_line":"                if shadow_role[\u0027name\u0027] not in existing_roles:"},{"line_number":123,"context_line":"                    msg \u003d _(\u0027Role %s does not exist.\u0027) % shadow_role[\u0027name\u0027]"},{"line_number":124,"context_line":"                    raise exception.RoleNotFound(msg)"},{"line_number":125,"context_line":"                role \u003d existing_roles[shadow_role[\u0027name\u0027]]"},{"line_number":126,"context_line":"                if (role[\u0027domain_id\u0027] is not None and"},{"line_number":127,"context_line":"                        role[\u0027domain_id\u0027] !\u003d idp_domain_id):"}],"source_content_type":"text/x-python","patch_set":15,"id":"5a3905b3_4748522e","line":124,"range":{"start_line":123,"start_character":20,"end_line":124,"end_character":53},"updated":"2017-01-19 05:16:48.000000000","message":"log something here so the user can fix their problem:\n\nLOG.error(\u0027Role %s was specified in the mapping but does not exist. All roles specified in a mapping must exist before users authenticate\u0027)","commit_id":"4ea0a20e02dad8816e49bf6b58b595db746ca385"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"5d97540db59356d698fe7fc47ba6ffb862089224","unresolved":false,"context_lines":[{"line_number":121,"context_line":"                # be useful."},{"line_number":122,"context_line":"                if shadow_role[\u0027name\u0027] not in existing_roles:"},{"line_number":123,"context_line":"                    msg \u003d _(\u0027Role %s does not exist.\u0027) % shadow_role[\u0027name\u0027]"},{"line_number":124,"context_line":"                    raise exception.RoleNotFound(msg)"},{"line_number":125,"context_line":"                role \u003d existing_roles[shadow_role[\u0027name\u0027]]"},{"line_number":126,"context_line":"                if (role[\u0027domain_id\u0027] is not None and"},{"line_number":127,"context_line":"                        role[\u0027domain_id\u0027] !\u003d idp_domain_id):"}],"source_content_type":"text/x-python","patch_set":15,"id":"5a3905b3_da6f9d90","line":124,"in_reply_to":"5a3905b3_1d3128a3","updated":"2017-01-19 15:16:27.000000000","message":"Done","commit_id":"4ea0a20e02dad8816e49bf6b58b595db746ca385"},{"author":{"_account_id":11022,"name":"Rodrigo Duarte Sousa","email":"rodrigodsousa@gmail.com","username":"rodrigods"},"change_message_id":"5bb4a7a9c0f87c4fe087fb2e1a2b7de03e16c50c","unresolved":false,"context_lines":[{"line_number":120,"context_line":"                # The role in the project mapping must exist in order for it to"},{"line_number":121,"context_line":"                # be useful."},{"line_number":122,"context_line":"                if shadow_role[\u0027name\u0027] not in existing_roles:"},{"line_number":123,"context_line":"                    msg \u003d _(\u0027Role %s does not exist.\u0027) % shadow_role[\u0027name\u0027]"},{"line_number":124,"context_line":"                    raise exception.RoleNotFound(msg)"},{"line_number":125,"context_line":"                role \u003d existing_roles[shadow_role[\u0027name\u0027]]"},{"line_number":126,"context_line":"                if (role[\u0027domain_id\u0027] is not None and"},{"line_number":127,"context_line":"                        role[\u0027domain_id\u0027] !\u003d idp_domain_id):"}],"source_content_type":"text/x-python","patch_set":15,"id":"5a3905b3_1d3128a3","line":124,"range":{"start_line":123,"start_character":20,"end_line":124,"end_character":53},"in_reply_to":"5a3905b3_4748522e","updated":"2017-01-19 13:11:36.000000000","message":"++","commit_id":"4ea0a20e02dad8816e49bf6b58b595db746ca385"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"5d97540db59356d698fe7fc47ba6ffb862089224","unresolved":false,"context_lines":[{"line_number":121,"context_line":"                # be useful."},{"line_number":122,"context_line":"                if shadow_role[\u0027name\u0027] not in existing_roles:"},{"line_number":123,"context_line":"                    msg \u003d _(\u0027Role %s does not exist.\u0027) % shadow_role[\u0027name\u0027]"},{"line_number":124,"context_line":"                    raise exception.RoleNotFound(msg)"},{"line_number":125,"context_line":"                role \u003d existing_roles[shadow_role[\u0027name\u0027]]"},{"line_number":126,"context_line":"                if (role[\u0027domain_id\u0027] is not None and"},{"line_number":127,"context_line":"                        role[\u0027domain_id\u0027] !\u003d idp_domain_id):"}],"source_content_type":"text/x-python","patch_set":15,"id":"5a3905b3_c57c1e23","line":124,"in_reply_to":"5a3905b3_4748522e","updated":"2017-01-19 15:16:27.000000000","message":"Done","commit_id":"4ea0a20e02dad8816e49bf6b58b595db746ca385"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"9c4342af51b64c3e1623b817508470590e6cab2a","unresolved":false,"context_lines":[{"line_number":125,"context_line":"                role \u003d existing_roles[shadow_role[\u0027name\u0027]]"},{"line_number":126,"context_line":"                if (role[\u0027domain_id\u0027] is not None and"},{"line_number":127,"context_line":"                        role[\u0027domain_id\u0027] !\u003d idp_domain_id):"},{"line_number":128,"context_line":"                    raise exception.InvalidDomainSpecificRole("},{"line_number":129,"context_line":"                        role_name\u003dshadow_role[\u0027name\u0027],"},{"line_number":130,"context_line":"                        identity_provider\u003didp_id"},{"line_number":131,"context_line":"                    )"}],"source_content_type":"text/x-python","patch_set":15,"id":"5a3905b3_075d6ae9","line":128,"range":{"start_line":128,"start_character":20,"end_line":128,"end_character":62},"updated":"2017-01-19 05:16:48.000000000","message":"same comment as above","commit_id":"4ea0a20e02dad8816e49bf6b58b595db746ca385"},{"author":{"_account_id":11022,"name":"Rodrigo Duarte Sousa","email":"rodrigodsousa@gmail.com","username":"rodrigods"},"change_message_id":"5bb4a7a9c0f87c4fe087fb2e1a2b7de03e16c50c","unresolved":false,"context_lines":[{"line_number":125,"context_line":"                role \u003d existing_roles[shadow_role[\u0027name\u0027]]"},{"line_number":126,"context_line":"                if (role[\u0027domain_id\u0027] is not None and"},{"line_number":127,"context_line":"                        role[\u0027domain_id\u0027] !\u003d idp_domain_id):"},{"line_number":128,"context_line":"                    raise exception.InvalidDomainSpecificRole("},{"line_number":129,"context_line":"                        role_name\u003dshadow_role[\u0027name\u0027],"},{"line_number":130,"context_line":"                        identity_provider\u003didp_id"},{"line_number":131,"context_line":"                    )"}],"source_content_type":"text/x-python","patch_set":15,"id":"5a3905b3_9d1d1812","line":128,"range":{"start_line":128,"start_character":20,"end_line":128,"end_character":62},"in_reply_to":"5a3905b3_075d6ae9","updated":"2017-01-19 13:11:36.000000000","message":"++","commit_id":"4ea0a20e02dad8816e49bf6b58b595db746ca385"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"5d97540db59356d698fe7fc47ba6ffb862089224","unresolved":false,"context_lines":[{"line_number":125,"context_line":"                role \u003d existing_roles[shadow_role[\u0027name\u0027]]"},{"line_number":126,"context_line":"                if (role[\u0027domain_id\u0027] is not None and"},{"line_number":127,"context_line":"                        role[\u0027domain_id\u0027] !\u003d idp_domain_id):"},{"line_number":128,"context_line":"                    raise exception.InvalidDomainSpecificRole("},{"line_number":129,"context_line":"                        role_name\u003dshadow_role[\u0027name\u0027],"},{"line_number":130,"context_line":"                        identity_provider\u003didp_id"},{"line_number":131,"context_line":"                    )"}],"source_content_type":"text/x-python","patch_set":15,"id":"5a3905b3_658d2a31","line":128,"in_reply_to":"5a3905b3_075d6ae9","updated":"2017-01-19 15:16:27.000000000","message":"Done","commit_id":"4ea0a20e02dad8816e49bf6b58b595db746ca385"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"5d97540db59356d698fe7fc47ba6ffb862089224","unresolved":false,"context_lines":[{"line_number":125,"context_line":"                role \u003d existing_roles[shadow_role[\u0027name\u0027]]"},{"line_number":126,"context_line":"                if (role[\u0027domain_id\u0027] is not None and"},{"line_number":127,"context_line":"                        role[\u0027domain_id\u0027] !\u003d idp_domain_id):"},{"line_number":128,"context_line":"                    raise exception.InvalidDomainSpecificRole("},{"line_number":129,"context_line":"                        role_name\u003dshadow_role[\u0027name\u0027],"},{"line_number":130,"context_line":"                        identity_provider\u003didp_id"},{"line_number":131,"context_line":"                    )"}],"source_content_type":"text/x-python","patch_set":15,"id":"5a3905b3_256082ce","line":128,"in_reply_to":"5a3905b3_9d1d1812","updated":"2017-01-19 15:16:27.000000000","message":"Done","commit_id":"4ea0a20e02dad8816e49bf6b58b595db746ca385"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"9c4342af51b64c3e1623b817508470590e6cab2a","unresolved":false,"context_lines":[{"line_number":146,"context_line":"                    \u0027name\u0027: shadow_project[\u0027name\u0027],"},{"line_number":147,"context_line":"                    \u0027domain_id\u0027: idp_domain_id"},{"line_number":148,"context_line":"                }"},{"line_number":149,"context_line":"                project \u003d resource_api.create_project("},{"line_number":150,"context_line":"                    project_ref[\u0027id\u0027],"},{"line_number":151,"context_line":"                    project_ref"},{"line_number":152,"context_line":"                )"},{"line_number":153,"context_line":""},{"line_number":154,"context_line":"            shadow_roles \u003d shadow_project[\u0027roles\u0027]"},{"line_number":155,"context_line":"            for shadow_role in shadow_roles:"}],"source_content_type":"text/x-python","patch_set":15,"id":"5a3905b3_87695a8e","line":152,"range":{"start_line":149,"start_character":0,"end_line":152,"end_character":17},"updated":"2017-01-19 05:16:48.000000000","message":"Log something here?\n\nLOG.info(\u0027Shadow project %s does not exist, it will be created automatically)","commit_id":"4ea0a20e02dad8816e49bf6b58b595db746ca385"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"5d97540db59356d698fe7fc47ba6ffb862089224","unresolved":false,"context_lines":[{"line_number":149,"context_line":"                project \u003d resource_api.create_project("},{"line_number":150,"context_line":"                    project_ref[\u0027id\u0027],"},{"line_number":151,"context_line":"                    project_ref"},{"line_number":152,"context_line":"                )"},{"line_number":153,"context_line":""},{"line_number":154,"context_line":"            shadow_roles \u003d shadow_project[\u0027roles\u0027]"},{"line_number":155,"context_line":"            for shadow_role in shadow_roles:"}],"source_content_type":"text/x-python","patch_set":15,"id":"5a3905b3_e592fa56","line":152,"in_reply_to":"5a3905b3_1dd84853","updated":"2017-01-19 15:16:27.000000000","message":"Done","commit_id":"4ea0a20e02dad8816e49bf6b58b595db746ca385"},{"author":{"_account_id":11022,"name":"Rodrigo Duarte Sousa","email":"rodrigodsousa@gmail.com","username":"rodrigods"},"change_message_id":"5bb4a7a9c0f87c4fe087fb2e1a2b7de03e16c50c","unresolved":false,"context_lines":[{"line_number":146,"context_line":"                    \u0027name\u0027: shadow_project[\u0027name\u0027],"},{"line_number":147,"context_line":"                    \u0027domain_id\u0027: idp_domain_id"},{"line_number":148,"context_line":"                }"},{"line_number":149,"context_line":"                project \u003d resource_api.create_project("},{"line_number":150,"context_line":"                    project_ref[\u0027id\u0027],"},{"line_number":151,"context_line":"                    project_ref"},{"line_number":152,"context_line":"                )"},{"line_number":153,"context_line":""},{"line_number":154,"context_line":"            shadow_roles \u003d shadow_project[\u0027roles\u0027]"},{"line_number":155,"context_line":"            for shadow_role in shadow_roles:"}],"source_content_type":"text/x-python","patch_set":15,"id":"5a3905b3_1dd84853","line":152,"range":{"start_line":149,"start_character":0,"end_line":152,"end_character":17},"in_reply_to":"5a3905b3_87695a8e","updated":"2017-01-19 13:11:36.000000000","message":"++","commit_id":"4ea0a20e02dad8816e49bf6b58b595db746ca385"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"5d97540db59356d698fe7fc47ba6ffb862089224","unresolved":false,"context_lines":[{"line_number":149,"context_line":"                project \u003d resource_api.create_project("},{"line_number":150,"context_line":"                    project_ref[\u0027id\u0027],"},{"line_number":151,"context_line":"                    project_ref"},{"line_number":152,"context_line":"                )"},{"line_number":153,"context_line":""},{"line_number":154,"context_line":"            shadow_roles \u003d shadow_project[\u0027roles\u0027]"},{"line_number":155,"context_line":"            for shadow_role in shadow_roles:"}],"source_content_type":"text/x-python","patch_set":15,"id":"5a3905b3_05a0e69e","line":152,"in_reply_to":"5a3905b3_87695a8e","updated":"2017-01-19 15:16:27.000000000","message":"Done","commit_id":"4ea0a20e02dad8816e49bf6b58b595db746ca385"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"9c4342af51b64c3e1623b817508470590e6cab2a","unresolved":false,"context_lines":[{"line_number":153,"context_line":""},{"line_number":154,"context_line":"            shadow_roles \u003d shadow_project[\u0027roles\u0027]"},{"line_number":155,"context_line":"            for shadow_role in shadow_roles:"},{"line_number":156,"context_line":"                assignment_api.create_grant("},{"line_number":157,"context_line":"                    existing_roles[shadow_role[\u0027name\u0027]][\u0027id\u0027],"},{"line_number":158,"context_line":"                    user_id\u003duser[\u0027id\u0027],"},{"line_number":159,"context_line":"                    project_id\u003dproject[\u0027id\u0027]"}],"source_content_type":"text/x-python","patch_set":15,"id":"5a3905b3_a7b9f6ee","line":156,"range":{"start_line":156,"start_character":16,"end_line":156,"end_character":44},"updated":"2017-01-19 05:16:48.000000000","message":"don\u0027t think you need to log anything here","commit_id":"4ea0a20e02dad8816e49bf6b58b595db746ca385"},{"author":{"_account_id":11022,"name":"Rodrigo Duarte Sousa","email":"rodrigodsousa@gmail.com","username":"rodrigods"},"change_message_id":"5bb4a7a9c0f87c4fe087fb2e1a2b7de03e16c50c","unresolved":false,"context_lines":[{"line_number":153,"context_line":""},{"line_number":154,"context_line":"            shadow_roles \u003d shadow_project[\u0027roles\u0027]"},{"line_number":155,"context_line":"            for shadow_role in shadow_roles:"},{"line_number":156,"context_line":"                assignment_api.create_grant("},{"line_number":157,"context_line":"                    existing_roles[shadow_role[\u0027name\u0027]][\u0027id\u0027],"},{"line_number":158,"context_line":"                    user_id\u003duser[\u0027id\u0027],"},{"line_number":159,"context_line":"                    project_id\u003dproject[\u0027id\u0027]"}],"source_content_type":"text/x-python","patch_set":15,"id":"5a3905b3_bdc81476","line":156,"range":{"start_line":156,"start_character":16,"end_line":156,"end_character":44},"in_reply_to":"5a3905b3_a7b9f6ee","updated":"2017-01-19 13:11:36.000000000","message":"++ the create_grant() should log itself","commit_id":"4ea0a20e02dad8816e49bf6b58b595db746ca385"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"5d97540db59356d698fe7fc47ba6ffb862089224","unresolved":false,"context_lines":[{"line_number":153,"context_line":""},{"line_number":154,"context_line":"            shadow_roles \u003d shadow_project[\u0027roles\u0027]"},{"line_number":155,"context_line":"            for shadow_role in shadow_roles:"},{"line_number":156,"context_line":"                assignment_api.create_grant("},{"line_number":157,"context_line":"                    existing_roles[shadow_role[\u0027name\u0027]][\u0027id\u0027],"},{"line_number":158,"context_line":"                    user_id\u003duser[\u0027id\u0027],"},{"line_number":159,"context_line":"                    project_id\u003dproject[\u0027id\u0027]"}],"source_content_type":"text/x-python","patch_set":15,"id":"5a3905b3_25740234","line":156,"in_reply_to":"5a3905b3_a7b9f6ee","updated":"2017-01-19 15:16:27.000000000","message":"Done","commit_id":"4ea0a20e02dad8816e49bf6b58b595db746ca385"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"5d97540db59356d698fe7fc47ba6ffb862089224","unresolved":false,"context_lines":[{"line_number":153,"context_line":""},{"line_number":154,"context_line":"            shadow_roles \u003d shadow_project[\u0027roles\u0027]"},{"line_number":155,"context_line":"            for shadow_role in shadow_roles:"},{"line_number":156,"context_line":"                assignment_api.create_grant("},{"line_number":157,"context_line":"                    existing_roles[shadow_role[\u0027name\u0027]][\u0027id\u0027],"},{"line_number":158,"context_line":"                    user_id\u003duser[\u0027id\u0027],"},{"line_number":159,"context_line":"                    project_id\u003dproject[\u0027id\u0027]"}],"source_content_type":"text/x-python","patch_set":15,"id":"5a3905b3_458f4e23","line":156,"in_reply_to":"5a3905b3_bdc81476","updated":"2017-01-19 15:16:27.000000000","message":"Done","commit_id":"4ea0a20e02dad8816e49bf6b58b595db746ca385"}],"keystone/exception.py":[{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"45664311e218158cc1f0dd67f170e54f05db4e4d","unresolved":false,"context_lines":[{"line_number":350,"context_line":""},{"line_number":351,"context_line":"class InvalidDomainSpecificRole(Forbidden):"},{"line_number":352,"context_line":"    message_format \u003d _(\"role: %(role_name)s must be within the same domain as \""},{"line_number":353,"context_line":"                       \"the identity provider: %(identity_provider)s.\")"},{"line_number":354,"context_line":""},{"line_number":355,"context_line":""},{"line_number":356,"context_line":"class RoleAssignmentNotFound(NotFound):"}],"source_content_type":"text/x-python","patch_set":8,"id":"9a57fde8_8193fca2","line":353,"updated":"2017-01-12 13:32:19.000000000","message":"Some messages end with a period and some don\u0027t :-( As a team we should be consistent.","commit_id":"545f20444fdc1d35528dde06ffdf34c609187cf5"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"b36693b5fbb5eb04f5ed2975e8d23e6326a5dbbb","unresolved":false,"context_lines":[{"line_number":350,"context_line":""},{"line_number":351,"context_line":"class InvalidDomainSpecificRole(Forbidden):"},{"line_number":352,"context_line":"    message_format \u003d _(\"role: %(role_name)s must be within the same domain as \""},{"line_number":353,"context_line":"                       \"the identity provider: %(identity_provider)s.\")"},{"line_number":354,"context_line":""},{"line_number":355,"context_line":""},{"line_number":356,"context_line":"class RoleAssignmentNotFound(NotFound):"}],"source_content_type":"text/x-python","patch_set":8,"id":"9a57fde8_95adf28a","line":353,"in_reply_to":"9a57fde8_8193fca2","updated":"2017-01-12 15:12:35.000000000","message":"I attempted to follow the convention from DomainSpecificRoleMismatch() and I totally agree. Maybe this is something we can do in a separate string of patches.","commit_id":"545f20444fdc1d35528dde06ffdf34c609187cf5"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"9c4342af51b64c3e1623b817508470590e6cab2a","unresolved":false,"context_lines":[{"line_number":348,"context_line":"                       \" as the role: %(role_id)s being assigned.\")"},{"line_number":349,"context_line":""},{"line_number":350,"context_line":""},{"line_number":351,"context_line":"class InvalidDomainSpecificRole(Forbidden):"},{"line_number":352,"context_line":"    message_format \u003d _(\"role: %(role_name)s must be within the same domain as \""},{"line_number":353,"context_line":"                       \"the identity provider: %(identity_provider)s.\")"},{"line_number":354,"context_line":""}],"source_content_type":"text/x-python","patch_set":15,"id":"5a3905b3_a72576af","line":351,"range":{"start_line":351,"start_character":6,"end_line":351,"end_character":31},"updated":"2017-01-19 05:16:48.000000000","message":"this is a pretty generic name for a very specific exception, \"Invalid\" makes me think of a validation that failed (like a schema validation)\n\nDomainSpecificRoleAndIdPMismatch ?","commit_id":"4ea0a20e02dad8816e49bf6b58b595db746ca385"},{"author":{"_account_id":11022,"name":"Rodrigo Duarte Sousa","email":"rodrigodsousa@gmail.com","username":"rodrigods"},"change_message_id":"5bb4a7a9c0f87c4fe087fb2e1a2b7de03e16c50c","unresolved":false,"context_lines":[{"line_number":348,"context_line":"                       \" as the role: %(role_id)s being assigned.\")"},{"line_number":349,"context_line":""},{"line_number":350,"context_line":""},{"line_number":351,"context_line":"class InvalidDomainSpecificRole(Forbidden):"},{"line_number":352,"context_line":"    message_format \u003d _(\"role: %(role_name)s must be within the same domain as \""},{"line_number":353,"context_line":"                       \"the identity provider: %(identity_provider)s.\")"},{"line_number":354,"context_line":""}],"source_content_type":"text/x-python","patch_set":15,"id":"5a3905b3_dd9c006c","line":351,"range":{"start_line":351,"start_character":6,"end_line":351,"end_character":31},"in_reply_to":"5a3905b3_a72576af","updated":"2017-01-19 13:11:36.000000000","message":"++","commit_id":"4ea0a20e02dad8816e49bf6b58b595db746ca385"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"5d97540db59356d698fe7fc47ba6ffb862089224","unresolved":false,"context_lines":[{"line_number":348,"context_line":"                       \" as the role: %(role_id)s being assigned.\")"},{"line_number":349,"context_line":""},{"line_number":350,"context_line":""},{"line_number":351,"context_line":"class InvalidDomainSpecificRole(Forbidden):"},{"line_number":352,"context_line":"    message_format \u003d _(\"role: %(role_name)s must be within the same domain as \""},{"line_number":353,"context_line":"                       \"the identity provider: %(identity_provider)s.\")"},{"line_number":354,"context_line":""}],"source_content_type":"text/x-python","patch_set":15,"id":"5a3905b3_c5f89e7f","line":351,"in_reply_to":"5a3905b3_dd9c006c","updated":"2017-01-19 15:16:27.000000000","message":"Aha - good point. Thanks!","commit_id":"4ea0a20e02dad8816e49bf6b58b595db746ca385"}],"keystone/federation/utils.py":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"2fc9c73b9d68300ceba0c7b9d93c7e2c025c0303","unresolved":false,"context_lines":[{"line_number":576,"context_line":"        group_names \u003d list()"},{"line_number":577,"context_line":"        groups_by_domain \u003d dict()"},{"line_number":578,"context_line":"        roles \u003d []"},{"line_number":579,"context_line":"        projects \u003d []"},{"line_number":580,"context_line":""},{"line_number":581,"context_line":"        # if mapping yield no valid identity values, we should bail right away"},{"line_number":582,"context_line":"        # instead of continuing on with a normalized bogus user"}],"source_content_type":"text/x-python","patch_set":1,"id":"ba5201f7_acdb87ec","line":579,"updated":"2016-12-30 19:08:59.000000000","message":"I had to add this in order to get the projects and the roles from the mapping into the mapped_properties. This is what I think should go into David\u0027s patch eventually.","commit_id":"c302751936f369aad732be91386aa0fbc51780f0"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"ebb17e5d84251139f085894097e3130c0a2be698","unresolved":false,"context_lines":[{"line_number":576,"context_line":"        group_names \u003d list()"},{"line_number":577,"context_line":"        groups_by_domain \u003d dict()"},{"line_number":578,"context_line":"        roles \u003d []"},{"line_number":579,"context_line":"        projects \u003d []"},{"line_number":580,"context_line":""},{"line_number":581,"context_line":"        # if mapping yield no valid identity values, we should bail right away"},{"line_number":582,"context_line":"        # instead of continuing on with a normalized bogus user"}],"source_content_type":"text/x-python","patch_set":1,"id":"ba5201f7_b78f58cb","line":579,"in_reply_to":"ba5201f7_acdb87ec","updated":"2017-01-09 17:30:36.000000000","message":"Done","commit_id":"c302751936f369aad732be91386aa0fbc51780f0"}],"keystone/tests/unit/mapping_fixtures.py":[{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"89062064c151893347bfd719a4ca3fbf428cfc4e","unresolved":false,"context_lines":[{"line_number":1592,"context_line":"MAPPING_PROJECTS \u003d {"},{"line_number":1593,"context_line":"    \"rules\": ["},{"line_number":1594,"context_line":"        {"},{"line_number":1595,"context_line":"            \"local\": ["},{"line_number":1596,"context_line":"                {"},{"line_number":1597,"context_line":"                    \"user\": {"},{"line_number":1598,"context_line":"                        \"name\": \"{0}\""},{"line_number":1599,"context_line":"                    }"},{"line_number":1600,"context_line":"                },"},{"line_number":1601,"context_line":"                {"},{"line_number":1602,"context_line":"                    \"projects\": ["},{"line_number":1603,"context_line":"                        {\"name\": \"Production\","}],"source_content_type":"text/x-python","patch_set":11,"id":"7a3c09a3_99952042","line":1600,"range":{"start_line":1595,"start_character":12,"end_line":1600,"end_character":18},"updated":"2017-01-13 15:37:25.000000000","message":"I think you need another mapping fixture that has projects and groups, so that we can prove that this works if both are in the mapping.","commit_id":"1323e6de47b4f723b81733d4c2a35c94cd0b8c52"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"ff87d499b98019552adde6b7aaf1af0d556dd82b","unresolved":false,"context_lines":[{"line_number":1597,"context_line":"                    \"user\": {"},{"line_number":1598,"context_line":"                        \"name\": \"{0}\""},{"line_number":1599,"context_line":"                    }"},{"line_number":1600,"context_line":"                },"},{"line_number":1601,"context_line":"                {"},{"line_number":1602,"context_line":"                    \"projects\": ["},{"line_number":1603,"context_line":"                        {\"name\": \"Production\","}],"source_content_type":"text/x-python","patch_set":11,"id":"7a3c09a3_12c74513","line":1600,"in_reply_to":"7a3c09a3_99952042","updated":"2017-01-13 16:22:00.000000000","message":"++ good call","commit_id":"1323e6de47b4f723b81733d4c2a35c94cd0b8c52"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"baa643c1223e8c9bfa886e57d248501edc5f59ab","unresolved":false,"context_lines":[{"line_number":1676,"context_line":"        },"},{"line_number":1677,"context_line":"    ]"},{"line_number":1678,"context_line":"}"},{"line_number":1679,"context_line":""},{"line_number":1680,"context_line":"# NOTE(lbragstad): I\u0027m putting this here because a case was brought up by a"},{"line_number":1681,"context_line":"# reviewer and leaving this in the code should help up generate some discussion"},{"line_number":1682,"context_line":"# around it. How should auto-provisioning work with groups in the mapping? The"}],"source_content_type":"text/x-python","patch_set":12,"id":"7a3c09a3_8170ecdd","line":1679,"updated":"2017-01-16 19:28:15.000000000","message":"Ron had a good comment on the last patch set about adding some cases where groups were also in the mapping. As I started working on implementing it, I had some questions because the RuleProcessor already has some logic around groups in the mappings identity_values. I wanted to add this here so that we could iterate on it in review, and capture whatever we come up with in that discussion.","commit_id":"617a3d95eabcfac21e1419fc0ca5904e832315a3"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"7c1274a3e13d9133f2ee1a951a7764bba3ab93fe","unresolved":false,"context_lines":[{"line_number":1684,"context_line":"# `groups`, and `group_ids` in the identity_values. Do we want a mapping"},{"line_number":1685,"context_line":"# similar to what\u0027s below where the user is placed in the \"Operators\" and"},{"line_number":1686,"context_line":"# \"Developers\" group? If those groups don\u0027t exist, do we create them like we do"},{"line_number":1687,"context_line":"# projects? The existing code in the RuleProcessor requires domains to also be"},{"line_number":1688,"context_line":"# in the mapping if only group names are available. Since we are now basing"},{"line_number":1689,"context_line":"# everything off the domain the Identity Provider is registered to, does this"},{"line_number":1690,"context_line":"# still hold true?"}],"source_content_type":"text/x-python","patch_set":12,"id":"7a3c09a3_c77be426","line":1687,"updated":"2017-01-16 20:10:29.000000000","message":"I don\u0027t think you should auto-create them for the same reason that I don\u0027t think we should automatically create roles. How useful is a group with no assignments? The question I have is should be add the user to the group in the database?","commit_id":"617a3d95eabcfac21e1419fc0ca5904e832315a3"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"af1a8e665922467131482e75dde0c865094e294b","unresolved":false,"context_lines":[{"line_number":1684,"context_line":"# `groups`, and `group_ids` in the identity_values. Do we want a mapping"},{"line_number":1685,"context_line":"# similar to what\u0027s below where the user is placed in the \"Operators\" and"},{"line_number":1686,"context_line":"# \"Developers\" group? If those groups don\u0027t exist, do we create them like we do"},{"line_number":1687,"context_line":"# projects? The existing code in the RuleProcessor requires domains to also be"},{"line_number":1688,"context_line":"# in the mapping if only group names are available. Since we are now basing"},{"line_number":1689,"context_line":"# everything off the domain the Identity Provider is registered to, does this"},{"line_number":1690,"context_line":"# still hold true?"}],"source_content_type":"text/x-python","patch_set":12,"id":"7a3c09a3_38ebe914","line":1687,"in_reply_to":"7a3c09a3_c77be426","updated":"2017-01-16 21:12:41.000000000","message":"Got it - I see what you mean. Creating groups on-the-fly would pose the same issue as creating role assignments. As far as your question goes I would assume that we have that ability now that we have a shadow user implementation. But, in digging through the code I can\u0027t seem to find where we explicitly add shadow users to groups from the mapping. This is confusing since the GET /v3/auth/projects API will return projects that user has access to via a group.\n\nLooking at the implementation of both the Mapped plugin and the GET /v3/auth/projects API makes it clear that we don\u0027t determine the groups a user is a member of from the user_id. Instead the Mapped plugin overrides the user_id and group_ids variables of the auth_context, which seem to be pulled out later and used in GET /v3/auth/projects.\n\nI think this case should be handled as a backwards compatibility fix for shadow users. The Mapped plugin never really took users into account since they were ephemeral. Now that we actually have a reference, we can check the group IDs and build the list of projects a user has access to based on the user id (which now points to a shadow user) and a list of groups that shadow user might be in.","commit_id":"617a3d95eabcfac21e1419fc0ca5904e832315a3"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"7c1274a3e13d9133f2ee1a951a7764bba3ab93fe","unresolved":false,"context_lines":[{"line_number":1687,"context_line":"# projects? The existing code in the RuleProcessor requires domains to also be"},{"line_number":1688,"context_line":"# in the mapping if only group names are available. Since we are now basing"},{"line_number":1689,"context_line":"# everything off the domain the Identity Provider is registered to, does this"},{"line_number":1690,"context_line":"# still hold true?"},{"line_number":1691,"context_line":"MAPPING_PROJECTS_AND_GROUPS \u003d {"},{"line_number":1692,"context_line":"    \"rules\": ["},{"line_number":1693,"context_line":"        {"}],"source_content_type":"text/x-python","patch_set":12,"id":"7a3c09a3_470b748e","line":1690,"updated":"2017-01-16 20:10:29.000000000","message":"I would say that we wouldn\u0027t need to require it anymore, but we should still accept it. We should also verify that the domain in the mapping is the same as the one the mapping is assigned to.","commit_id":"617a3d95eabcfac21e1419fc0ca5904e832315a3"}],"keystone/tests/unit/test_v3_federation.py":[{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"cb5fa356c96ee6eb89f9b176c5cc866e82dec12b","unresolved":false,"context_lines":[{"line_number":3146,"context_line":"                project[\u0027name\u0027],"},{"line_number":3147,"context_line":"                self.idp[\u0027domain_id\u0027]"},{"line_number":3148,"context_line":"            )"},{"line_number":3149,"context_line":"            self.assertIn(project[\u0027name\u0027], self.expected_results.keys())"},{"line_number":3150,"context_line":""},{"line_number":3151,"context_line":"    def test_shadow_mapping_create_projects_role_assignments(self):"},{"line_number":3152,"context_line":"        response \u003d self._issue_unscoped_token()"}],"source_content_type":"text/x-python","patch_set":1,"id":"ba5201f7_02585a89","line":3149,"updated":"2017-01-05 13:54:00.000000000","message":"You can drop \u0027.keys()\u0027 here too","commit_id":"c302751936f369aad732be91386aa0fbc51780f0"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"4c29a3eb2981dc1614e705e4c0fb1c29487f6112","unresolved":false,"context_lines":[{"line_number":3146,"context_line":"                project[\u0027name\u0027],"},{"line_number":3147,"context_line":"                self.idp[\u0027domain_id\u0027]"},{"line_number":3148,"context_line":"            )"},{"line_number":3149,"context_line":"            self.assertIn(project[\u0027name\u0027], self.expected_results.keys())"},{"line_number":3150,"context_line":""},{"line_number":3151,"context_line":"    def test_shadow_mapping_create_projects_role_assignments(self):"},{"line_number":3152,"context_line":"        response \u003d self._issue_unscoped_token()"}],"source_content_type":"text/x-python","patch_set":1,"id":"ba5201f7_2880cdbf","line":3149,"in_reply_to":"ba5201f7_02585a89","updated":"2017-01-05 21:45:39.000000000","message":"Done","commit_id":"c302751936f369aad732be91386aa0fbc51780f0"},{"author":{"_account_id":11022,"name":"Rodrigo Duarte Sousa","email":"rodrigodsousa@gmail.com","username":"rodrigods"},"change_message_id":"bf348de83b84daad9f3c8ec252d64d9046dc6d3d","unresolved":false,"context_lines":[{"line_number":1701,"context_line":"                 body\u003d{\u0027mapping\u0027: bad_mapping})"},{"line_number":1702,"context_line":""},{"line_number":1703,"context_line":"    def test_create_shadow_mapping_without_roles_fails(self):"},{"line_number":1704,"context_line":"        # If a mapping contains projects, those projects should also contain"},{"line_number":1705,"context_line":"        # roles so that it\u0027s possible to determine which role a user should"},{"line_number":1706,"context_line":"        # have on a project in their mapping."},{"line_number":1707,"context_line":"        url \u003d self.MAPPING_URL + uuid.uuid4().hex"},{"line_number":1708,"context_line":"        self.put("},{"line_number":1709,"context_line":"            url,"}],"source_content_type":"text/x-python","patch_set":7,"id":"ba5201f7_70267a69","line":1706,"range":{"start_line":1704,"start_character":8,"end_line":1706,"end_character":45},"updated":"2017-01-11 11:56:24.000000000","message":"nit: this comment and others below are more suitable as docstrings in the tests.","commit_id":"69cba05587abf23b6d48d351c29cdc2db5c0d654"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"47ad6893f659fd1907a27cd272e53089dc19ede5","unresolved":false,"context_lines":[{"line_number":1703,"context_line":"    def test_create_shadow_mapping_without_roles_fails(self):"},{"line_number":1704,"context_line":"        # If a mapping contains projects, those projects should also contain"},{"line_number":1705,"context_line":"        # roles so that it\u0027s possible to determine which role a user should"},{"line_number":1706,"context_line":"        # have on a project in their mapping."},{"line_number":1707,"context_line":"        url \u003d self.MAPPING_URL + uuid.uuid4().hex"},{"line_number":1708,"context_line":"        self.put("},{"line_number":1709,"context_line":"            url,"}],"source_content_type":"text/x-python","patch_set":7,"id":"ba5201f7_82546d54","line":1706,"in_reply_to":"ba5201f7_70267a69","updated":"2017-01-11 15:57:47.000000000","message":"Done","commit_id":"69cba05587abf23b6d48d351c29cdc2db5c0d654"},{"author":{"_account_id":11022,"name":"Rodrigo Duarte Sousa","email":"rodrigodsousa@gmail.com","username":"rodrigods"},"change_message_id":"bf348de83b84daad9f3c8ec252d64d9046dc6d3d","unresolved":false,"context_lines":[{"line_number":3160,"context_line":"                self.expected_results[project_name], roles[0][\u0027name\u0027]"},{"line_number":3161,"context_line":"            )"},{"line_number":3162,"context_line":""},{"line_number":3163,"context_line":"    def test_shadow_mapping_does_not_create_roles(self):"},{"line_number":3164,"context_line":"        # If a role required by the mapping does not exist, then we should fail"},{"line_number":3165,"context_line":"        # the mapping since shadow mapping currently does not support creating"},{"line_number":3166,"context_line":"        # mappings on-the-fly."}],"source_content_type":"text/x-python","patch_set":7,"id":"ba5201f7_f0f18ace","line":3163,"range":{"start_line":3163,"start_character":8,"end_line":3163,"end_character":49},"updated":"2017-01-11 11:56:24.000000000","message":"nice test!","commit_id":"69cba05587abf23b6d48d351c29cdc2db5c0d654"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"47ad6893f659fd1907a27cd272e53089dc19ede5","unresolved":false,"context_lines":[{"line_number":3160,"context_line":"                self.expected_results[project_name], roles[0][\u0027name\u0027]"},{"line_number":3161,"context_line":"            )"},{"line_number":3162,"context_line":""},{"line_number":3163,"context_line":"    def test_shadow_mapping_does_not_create_roles(self):"},{"line_number":3164,"context_line":"        # If a role required by the mapping does not exist, then we should fail"},{"line_number":3165,"context_line":"        # the mapping since shadow mapping currently does not support creating"},{"line_number":3166,"context_line":"        # mappings on-the-fly."}],"source_content_type":"text/x-python","patch_set":7,"id":"ba5201f7_e249b9b8","line":3163,"in_reply_to":"ba5201f7_f0f18ace","updated":"2017-01-11 15:57:47.000000000","message":"thanks!","commit_id":"69cba05587abf23b6d48d351c29cdc2db5c0d654"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"72a3ab0f2ad50e6da7b0c3b8b71fbd78dfcca0ea","unresolved":false,"context_lines":[{"line_number":3133,"context_line":"        response \u003d self.get(\u0027/auth/projects\u0027, token\u003dunscoped_token)"},{"line_number":3134,"context_line":"        projects \u003d response.json_body[\u0027projects\u0027]"},{"line_number":3135,"context_line":"        for project in projects:"},{"line_number":3136,"context_line":"            # Ensure that the projects in the mapping were actually created."},{"line_number":3137,"context_line":"            project \u003d self.resource_api.get_project_by_name("},{"line_number":3138,"context_line":"                project[\u0027name\u0027],"},{"line_number":3139,"context_line":"                self.idp[\u0027domain_id\u0027]"}],"source_content_type":"text/x-python","patch_set":8,"id":"9a57fde8_646d4632","line":3136,"updated":"2017-01-12 14:23:06.000000000","message":"How do we know that they didn\u0027t already exist?","commit_id":"545f20444fdc1d35528dde06ffdf34c609187cf5"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"b36693b5fbb5eb04f5ed2975e8d23e6326a5dbbb","unresolved":false,"context_lines":[{"line_number":3133,"context_line":"        response \u003d self.get(\u0027/auth/projects\u0027, token\u003dunscoped_token)"},{"line_number":3134,"context_line":"        projects \u003d response.json_body[\u0027projects\u0027]"},{"line_number":3135,"context_line":"        for project in projects:"},{"line_number":3136,"context_line":"            # Ensure that the projects in the mapping were actually created."},{"line_number":3137,"context_line":"            project \u003d self.resource_api.get_project_by_name("},{"line_number":3138,"context_line":"                project[\u0027name\u0027],"},{"line_number":3139,"context_line":"                self.idp[\u0027domain_id\u0027]"}],"source_content_type":"text/x-python","patch_set":8,"id":"9a57fde8_d5dcda1a","line":3136,"in_reply_to":"9a57fde8_646d4632","updated":"2017-01-12 15:12:35.000000000","message":"They totally can. I can add some assertions here to attempt to grab them before authentication.","commit_id":"545f20444fdc1d35528dde06ffdf34c609187cf5"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"72a3ab0f2ad50e6da7b0c3b8b71fbd78dfcca0ea","unresolved":false,"context_lines":[{"line_number":3165,"context_line":"        # the mapping since shadow mapping currently does not support creating"},{"line_number":3166,"context_line":"        # mappings on-the-fly."},{"line_number":3167,"context_line":"        self.role_api.delete_role(self.observer_role[\u0027id\u0027])"},{"line_number":3168,"context_line":"        self.assertRaises(exception.RoleNotFound, self._issue_unscoped_token)"},{"line_number":3169,"context_line":""},{"line_number":3170,"context_line":"    def test_shadow_mapping_creates_project_in_identity_provider_domain(self):"},{"line_number":3171,"context_line":"        response \u003d self._issue_unscoped_token()"}],"source_content_type":"text/x-python","patch_set":8,"id":"9a57fde8_e4c69615","line":3168,"updated":"2017-01-12 14:23:06.000000000","message":"Does this mean that a user gets a 404? That doesn\u0027t seem right.","commit_id":"545f20444fdc1d35528dde06ffdf34c609187cf5"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"b36693b5fbb5eb04f5ed2975e8d23e6326a5dbbb","unresolved":false,"context_lines":[{"line_number":3165,"context_line":"        # the mapping since shadow mapping currently does not support creating"},{"line_number":3166,"context_line":"        # mappings on-the-fly."},{"line_number":3167,"context_line":"        self.role_api.delete_role(self.observer_role[\u0027id\u0027])"},{"line_number":3168,"context_line":"        self.assertRaises(exception.RoleNotFound, self._issue_unscoped_token)"},{"line_number":3169,"context_line":""},{"line_number":3170,"context_line":"    def test_shadow_mapping_creates_project_in_identity_provider_domain(self):"},{"line_number":3171,"context_line":"        response \u003d self._issue_unscoped_token()"}],"source_content_type":"text/x-python","patch_set":8,"id":"9a57fde8_f093ac4d","line":3168,"in_reply_to":"9a57fde8_e4c69615","updated":"2017-01-12 15:12:35.000000000","message":"It would - but the only way I could think of preventing it would be to have some sort of relationship between the roles and if they are used in the mapping at all. An example might be checking that a role doesn\u0027t exist in a mapping when we delete it, or using a FK relationship.\n\nThoughts?","commit_id":"545f20444fdc1d35528dde06ffdf34c609187cf5"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"72a3ab0f2ad50e6da7b0c3b8b71fbd78dfcca0ea","unresolved":false,"context_lines":[{"line_number":3176,"context_line":"        for project in projects:"},{"line_number":3177,"context_line":"            self.assertEqual(project[\u0027domain_id\u0027], self.idp[\u0027domain_id\u0027])"},{"line_number":3178,"context_line":""},{"line_number":3179,"context_line":"    def test_shadow_mapping_is_idempotent(self):"},{"line_number":3180,"context_line":"        response \u003d self._issue_unscoped_token()"},{"line_number":3181,"context_line":"        self.assertValidMappedUser(response.json_body[\u0027token\u0027])"},{"line_number":3182,"context_line":"        unscoped_token \u003d response.headers.get(\u0027X-Subject-Token\u0027)"}],"source_content_type":"text/x-python","patch_set":8,"id":"9a57fde8_47f844e6","line":3179,"updated":"2017-01-12 14:23:06.000000000","message":"Should add a docstring saying what exactly is idempotent","commit_id":"545f20444fdc1d35528dde06ffdf34c609187cf5"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"b36693b5fbb5eb04f5ed2975e8d23e6326a5dbbb","unresolved":false,"context_lines":[{"line_number":3176,"context_line":"        for project in projects:"},{"line_number":3177,"context_line":"            self.assertEqual(project[\u0027domain_id\u0027], self.idp[\u0027domain_id\u0027])"},{"line_number":3178,"context_line":""},{"line_number":3179,"context_line":"    def test_shadow_mapping_is_idempotent(self):"},{"line_number":3180,"context_line":"        response \u003d self._issue_unscoped_token()"},{"line_number":3181,"context_line":"        self.assertValidMappedUser(response.json_body[\u0027token\u0027])"},{"line_number":3182,"context_line":"        unscoped_token \u003d response.headers.get(\u0027X-Subject-Token\u0027)"}],"source_content_type":"text/x-python","patch_set":8,"id":"9a57fde8_10fe706b","line":3179,"in_reply_to":"9a57fde8_47f844e6","updated":"2017-01-12 15:12:35.000000000","message":"Done","commit_id":"545f20444fdc1d35528dde06ffdf34c609187cf5"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"72a3ab0f2ad50e6da7b0c3b8b71fbd78dfcca0ea","unresolved":false,"context_lines":[{"line_number":3182,"context_line":"        unscoped_token \u003d response.headers.get(\u0027X-Subject-Token\u0027)"},{"line_number":3183,"context_line":"        response \u003d self.get(\u0027/auth/projects\u0027, token\u003dunscoped_token)"},{"line_number":3184,"context_line":"        projects \u003d response.json_body[\u0027projects\u0027]"},{"line_number":3185,"context_line":"        project_ids \u003d []"},{"line_number":3186,"context_line":"        for project in projects:"},{"line_number":3187,"context_line":"            project_ids.append(project[\u0027id\u0027])"},{"line_number":3188,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"9a57fde8_87378ce2","line":3185,"updated":"2017-01-12 14:23:06.000000000","message":"suggest: project_ids \u003d [p[\u0027id\u0027] for p in response.json_body[\u0027projects\u0027]]","commit_id":"545f20444fdc1d35528dde06ffdf34c609187cf5"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"b36693b5fbb5eb04f5ed2975e8d23e6326a5dbbb","unresolved":false,"context_lines":[{"line_number":3182,"context_line":"        unscoped_token \u003d response.headers.get(\u0027X-Subject-Token\u0027)"},{"line_number":3183,"context_line":"        response \u003d self.get(\u0027/auth/projects\u0027, token\u003dunscoped_token)"},{"line_number":3184,"context_line":"        projects \u003d response.json_body[\u0027projects\u0027]"},{"line_number":3185,"context_line":"        project_ids \u003d []"},{"line_number":3186,"context_line":"        for project in projects:"},{"line_number":3187,"context_line":"            project_ids.append(project[\u0027id\u0027])"},{"line_number":3188,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"9a57fde8_503f1825","line":3185,"in_reply_to":"9a57fde8_87378ce2","updated":"2017-01-12 15:12:35.000000000","message":"Done","commit_id":"545f20444fdc1d35528dde06ffdf34c609187cf5"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"72a3ab0f2ad50e6da7b0c3b8b71fbd78dfcca0ea","unresolved":false,"context_lines":[{"line_number":3228,"context_line":"        )"},{"line_number":3229,"context_line":"        for project in projects:"},{"line_number":3230,"context_line":"            # Even though the mapping successfully assigned the Staging project"},{"line_number":3231,"context_line":"            # a member role for our user, the /auth/project/ response doesn\u0027t"},{"line_number":3232,"context_line":"            # include projects with only domain-specific role assignments."},{"line_number":3233,"context_line":"            self.assertNotEqual(project[\u0027name\u0027], \u0027Staging\u0027)"},{"line_number":3234,"context_line":"        domain_role_assignments \u003d self.assignment_api.list_role_assignments("}],"source_content_type":"text/x-python","patch_set":8,"id":"9a57fde8_6789c8ca","line":3231,"updated":"2017-01-12 14:23:06.000000000","message":"/auth/projects","commit_id":"545f20444fdc1d35528dde06ffdf34c609187cf5"},{"author":{"_account_id":11022,"name":"Rodrigo Duarte Sousa","email":"rodrigodsousa@gmail.com","username":"rodrigods"},"change_message_id":"2309b31544f61ca9fa8c012d527ca0a8f92d4ddc","unresolved":false,"context_lines":[{"line_number":3227,"context_line":"            \u0027Staging\u0027, self.idp[\u0027domain_id\u0027]"},{"line_number":3228,"context_line":"        )"},{"line_number":3229,"context_line":"        for project in projects:"},{"line_number":3230,"context_line":"            # Even though the mapping successfully assigned the Staging project"},{"line_number":3231,"context_line":"            # a member role for our user, the /auth/project/ response doesn\u0027t"},{"line_number":3232,"context_line":"            # include projects with only domain-specific role assignments."},{"line_number":3233,"context_line":"            self.assertNotEqual(project[\u0027name\u0027], \u0027Staging\u0027)"},{"line_number":3234,"context_line":"        domain_role_assignments \u003d self.assignment_api.list_role_assignments("}],"source_content_type":"text/x-python","patch_set":8,"id":"ba5201f7_d6b0e945","line":3231,"range":{"start_line":3230,"start_character":14,"end_line":3231,"end_character":77},"updated":"2017-01-11 18:06:54.000000000","message":"nice!","commit_id":"545f20444fdc1d35528dde06ffdf34c609187cf5"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"b36693b5fbb5eb04f5ed2975e8d23e6326a5dbbb","unresolved":false,"context_lines":[{"line_number":3228,"context_line":"        )"},{"line_number":3229,"context_line":"        for project in projects:"},{"line_number":3230,"context_line":"            # Even though the mapping successfully assigned the Staging project"},{"line_number":3231,"context_line":"            # a member role for our user, the /auth/project/ response doesn\u0027t"},{"line_number":3232,"context_line":"            # include projects with only domain-specific role assignments."},{"line_number":3233,"context_line":"            self.assertNotEqual(project[\u0027name\u0027], \u0027Staging\u0027)"},{"line_number":3234,"context_line":"        domain_role_assignments \u003d self.assignment_api.list_role_assignments("}],"source_content_type":"text/x-python","patch_set":8,"id":"9a57fde8_9020a0f9","line":3231,"in_reply_to":"9a57fde8_6789c8ca","updated":"2017-01-12 15:12:35.000000000","message":"Done","commit_id":"545f20444fdc1d35528dde06ffdf34c609187cf5"},{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"89062064c151893347bfd719a4ca3fbf428cfc4e","unresolved":false,"context_lines":[{"line_number":3100,"context_line":"        # global roles and not domain-scoped roles. We have specific tests"},{"line_number":3101,"context_line":"        # below that test that behavior and the setup is done in the test."},{"line_number":3102,"context_line":"        member_role_ref \u003d unit.new_role_ref(name\u003d\u0027member\u0027)"},{"line_number":3103,"context_line":"        assert member_role_ref[\u0027domain_id\u0027] is None"},{"line_number":3104,"context_line":"        self.member_role \u003d self.role_api.create_role("},{"line_number":3105,"context_line":"            member_role_ref[\u0027id\u0027], member_role_ref"},{"line_number":3106,"context_line":"        )"}],"source_content_type":"text/x-python","patch_set":11,"id":"7a3c09a3_797234e7","line":3103,"range":{"start_line":3103,"start_character":8,"end_line":3103,"end_character":51},"updated":"2017-01-13 15:37:25.000000000","message":"Why asserting this is None?","commit_id":"1323e6de47b4f723b81733d4c2a35c94cd0b8c52"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"ff87d499b98019552adde6b7aaf1af0d556dd82b","unresolved":false,"context_lines":[{"line_number":3100,"context_line":"        # global roles and not domain-scoped roles. We have specific tests"},{"line_number":3101,"context_line":"        # below that test that behavior and the setup is done in the test."},{"line_number":3102,"context_line":"        member_role_ref \u003d unit.new_role_ref(name\u003d\u0027member\u0027)"},{"line_number":3103,"context_line":"        assert member_role_ref[\u0027domain_id\u0027] is None"},{"line_number":3104,"context_line":"        self.member_role \u003d self.role_api.create_role("},{"line_number":3105,"context_line":"            member_role_ref[\u0027id\u0027], member_role_ref"},{"line_number":3106,"context_line":"        )"}],"source_content_type":"text/x-python","patch_set":11,"id":"7a3c09a3_9277b5d3","line":3103,"in_reply_to":"7a3c09a3_797234e7","updated":"2017-01-13 16:22:00.000000000","message":"The comment above talks about making sure these are global roles and not domain-scoped roles.","commit_id":"1323e6de47b4f723b81733d4c2a35c94cd0b8c52"},{"author":{"_account_id":16465,"name":"Kristi Nikolla","email":"knikolla@bu.edu","username":"knikolla"},"change_message_id":"44d61f34b27ba0fa2b586531a5aad6a3c67dc954","unresolved":false,"context_lines":[{"line_number":3134,"context_line":"        response \u003d self._issue_unscoped_token()"},{"line_number":3135,"context_line":"        self.assertValidMappedUser(response.json_body[\u0027token\u0027])"},{"line_number":3136,"context_line":"        unscoped_token \u003d response.headers.get(\u0027X-Subject-Token\u0027)"},{"line_number":3137,"context_line":"        response \u003d self.get(\u0027/auth/projects\u0027, token\u003dunscoped_token)"},{"line_number":3138,"context_line":"        projects \u003d response.json_body[\u0027projects\u0027]"},{"line_number":3139,"context_line":"        for project in projects:"},{"line_number":3140,"context_line":"            project \u003d self.resource_api.get_project_by_name("}],"source_content_type":"text/x-python","patch_set":11,"id":"7a3c09a3_7a220903","line":3137,"updated":"2017-01-14 14:43:38.000000000","message":"What is the difference between /v3/OS-FEDERATION/projects and /auth/projects? Is this possible because of shadow users or the new shadow mapping features?","commit_id":"1323e6de47b4f723b81733d4c2a35c94cd0b8c52"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"ee939b456d6aeae9e18501b333aa262287062a7d","unresolved":false,"context_lines":[{"line_number":3134,"context_line":"        response \u003d self._issue_unscoped_token()"},{"line_number":3135,"context_line":"        self.assertValidMappedUser(response.json_body[\u0027token\u0027])"},{"line_number":3136,"context_line":"        unscoped_token \u003d response.headers.get(\u0027X-Subject-Token\u0027)"},{"line_number":3137,"context_line":"        response \u003d self.get(\u0027/auth/projects\u0027, token\u003dunscoped_token)"},{"line_number":3138,"context_line":"        projects \u003d response.json_body[\u0027projects\u0027]"},{"line_number":3139,"context_line":"        for project in projects:"},{"line_number":3140,"context_line":"            project \u003d self.resource_api.get_project_by_name("}],"source_content_type":"text/x-python","patch_set":11,"id":"7a3c09a3_f8dc1714","line":3137,"in_reply_to":"7a3c09a3_7a220903","updated":"2017-01-16 15:23:41.000000000","message":"There shouldn\u0027t be any difference between those two API. If I recall correctly, the /auth/projects API was modified to handle the cases used by /v3/OS-FEDERATION/auth/projects. So you should be able to use /auth/projects/ with federated tokens.","commit_id":"1323e6de47b4f723b81733d4c2a35c94cd0b8c52"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"9c4342af51b64c3e1623b817508470590e6cab2a","unresolved":false,"context_lines":[{"line_number":3110,"context_line":"            observer_role_ref[\u0027id\u0027], observer_role_ref"},{"line_number":3111,"context_line":"        )"},{"line_number":3112,"context_line":""},{"line_number":3113,"context_line":"        # This is a mapping of the project name to the role that is suppose to"},{"line_number":3114,"context_line":"        # be assigned to the user on that project from the shadow mapping."},{"line_number":3115,"context_line":"        self.expected_results \u003d {"},{"line_number":3116,"context_line":"            \u0027Production\u0027: \u0027observer\u0027,"}],"source_content_type":"text/x-python","patch_set":15,"id":"5a3905b3_e7593e90","line":3113,"range":{"start_line":3113,"start_character":68,"end_line":3113,"end_character":75},"updated":"2017-01-19 05:16:48.000000000","message":"supposed*","commit_id":"4ea0a20e02dad8816e49bf6b58b595db746ca385"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"5d97540db59356d698fe7fc47ba6ffb862089224","unresolved":false,"context_lines":[{"line_number":3110,"context_line":"            observer_role_ref[\u0027id\u0027], observer_role_ref"},{"line_number":3111,"context_line":"        )"},{"line_number":3112,"context_line":""},{"line_number":3113,"context_line":"        # This is a mapping of the project name to the role that is suppose to"},{"line_number":3114,"context_line":"        # be assigned to the user on that project from the shadow mapping."},{"line_number":3115,"context_line":"        self.expected_results \u003d {"},{"line_number":3116,"context_line":"            \u0027Production\u0027: \u0027observer\u0027,"}],"source_content_type":"text/x-python","patch_set":15,"id":"5a3905b3_a5d632c3","line":3113,"in_reply_to":"5a3905b3_e7593e90","updated":"2017-01-19 15:16:27.000000000","message":"Done","commit_id":"4ea0a20e02dad8816e49bf6b58b595db746ca385"}],"releasenotes/notes/implement-shadow-mapping-06fc7c71a401d707.yaml":[{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"45664311e218158cc1f0dd67f170e54f05db4e4d","unresolved":false,"context_lines":[{"line_number":5,"context_line":"    created for a user at the time of federated login, based"},{"line_number":6,"context_line":"    solely on the mapping. This feature maintains support"},{"line_number":7,"context_line":"    for existing mappings, but adds some enhancements to the"},{"line_number":8,"context_line":"    mapping engine to be able to auto-provision resources in"},{"line_number":9,"context_line":"    federated workflows."}],"source_content_type":"text/x-yaml","patch_set":8,"id":"9a57fde8_a1f1e0cf","line":8,"updated":"2017-01-12 13:32:19.000000000","message":"suggest: mapping engine to enable auto-provisioning of resources in","commit_id":"545f20444fdc1d35528dde06ffdf34c609187cf5"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"b36693b5fbb5eb04f5ed2975e8d23e6326a5dbbb","unresolved":false,"context_lines":[{"line_number":5,"context_line":"    created for a user at the time of federated login, based"},{"line_number":6,"context_line":"    solely on the mapping. This feature maintains support"},{"line_number":7,"context_line":"    for existing mappings, but adds some enhancements to the"},{"line_number":8,"context_line":"    mapping engine to be able to auto-provision resources in"},{"line_number":9,"context_line":"    federated workflows."}],"source_content_type":"text/x-yaml","patch_set":8,"id":"9a57fde8_70517c62","line":8,"in_reply_to":"9a57fde8_a1f1e0cf","updated":"2017-01-12 15:12:35.000000000","message":"Done","commit_id":"545f20444fdc1d35528dde06ffdf34c609187cf5"},{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"4c92e6ee3589132ecf018f0bc23aafe249b5c248","unresolved":false,"context_lines":[{"line_number":1,"context_line":"---"},{"line_number":2,"context_line":"features:"},{"line_number":3,"context_line":"  - Support is now available for shadow mapping. Shadow"},{"line_number":4,"context_line":"    mapping allows projects and role assignments to be"},{"line_number":5,"context_line":"    created for a user at the time of federated login, based"},{"line_number":6,"context_line":"    solely on the mapping. This feature maintains support"},{"line_number":7,"context_line":"    for existing mappings, but adds some enhancements to the"},{"line_number":8,"context_line":"    mapping engine to enable auto-provisioning of resources"},{"line_number":9,"context_line":"    in federated workflows."}],"source_content_type":"text/x-yaml","patch_set":10,"id":"9a57fde8_f4bb9773","line":9,"range":{"start_line":3,"start_character":3,"end_line":9,"end_character":27},"updated":"2017-01-12 18:05:07.000000000","message":"I think it would be better if you removed references to shadow mapping and the mapping engine. Instead, something describes the feature for operators, such as \"we\u0027ve extended our federated capabilities to allow you to map your federated users into local projects and roles...\"  I do like \"enable auto-provisioning of resources in federated workflows.\" Anyway, that\u0027s my 2 cents :)","commit_id":"73e00996188c8ae3ce2707c1789ec0cf5c98e2eb"},{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"2fbca3b11356adc0ca810ba843d624dfbf7ab66b","unresolved":false,"context_lines":[{"line_number":6,"context_line":"    solely on the mapping. This feature maintains support"},{"line_number":7,"context_line":"    for existing mappings, but adds some enhancements to the"},{"line_number":8,"context_line":"    mapping engine to enable auto-provisioning of resources"},{"line_number":9,"context_line":"    in federated workflows."}],"source_content_type":"text/x-yaml","patch_set":10,"id":"9a57fde8_f4e552a8","line":9,"in_reply_to":"9a57fde8_345efae9","updated":"2017-01-12 19:36:03.000000000","message":"Haha, that\u0027s stevemar\u0027s job ;)","commit_id":"73e00996188c8ae3ce2707c1789ec0cf5c98e2eb"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"386fc2a6287d7340429fa823d31ff8a02a70d3e5","unresolved":false,"context_lines":[{"line_number":6,"context_line":"    solely on the mapping. This feature maintains support"},{"line_number":7,"context_line":"    for existing mappings, but adds some enhancements to the"},{"line_number":8,"context_line":"    mapping engine to enable auto-provisioning of resources"},{"line_number":9,"context_line":"    in federated workflows."}],"source_content_type":"text/x-yaml","patch_set":10,"id":"9a57fde8_345efae9","line":9,"in_reply_to":"9a57fde8_f4bb9773","updated":"2017-01-12 19:34:02.000000000","message":"You should add \"word-smith\" to your professional title! ;)\n\nGreat suggestions, thanks!","commit_id":"73e00996188c8ae3ce2707c1789ec0cf5c98e2eb"},{"author":{"_account_id":16465,"name":"Kristi Nikolla","email":"knikolla@bu.edu","username":"knikolla"},"change_message_id":"44d61f34b27ba0fa2b586531a5aad6a3c67dc954","unresolved":false,"context_lines":[{"line_number":1,"context_line":"---"},{"line_number":2,"context_line":"features:"},{"line_number":3,"context_line":"  - The federated mapping engine now supports the ability"},{"line_number":4,"context_line":"    to map federated (shadow) users into local projects,"},{"line_number":5,"context_line":"    granting them access with local roles. This can be done"},{"line_number":6,"context_line":"    using a specific mapping syntax. This feature maintains"},{"line_number":7,"context_line":"    support for existing mappings, but adds some enhancements"}],"source_content_type":"text/x-yaml","patch_set":11,"id":"7a3c09a3_9afdf53c","line":4,"range":{"start_line":4,"start_character":41,"end_line":4,"end_character":55},"updated":"2017-01-14 14:43:38.000000000","message":"Should mention the restriction that the projects must be within the identity provider\u0027s domain. It\u0027s what breaks my use case for this.","commit_id":"1323e6de47b4f723b81733d4c2a35c94cd0b8c52"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"ee939b456d6aeae9e18501b333aa262287062a7d","unresolved":false,"context_lines":[{"line_number":1,"context_line":"---"},{"line_number":2,"context_line":"features:"},{"line_number":3,"context_line":"  - The federated mapping engine now supports the ability"},{"line_number":4,"context_line":"    to map federated (shadow) users into local projects,"},{"line_number":5,"context_line":"    granting them access with local roles. This can be done"},{"line_number":6,"context_line":"    using a specific mapping syntax. This feature maintains"},{"line_number":7,"context_line":"    support for existing mappings, but adds some enhancements"}],"source_content_type":"text/x-yaml","patch_set":11,"id":"7a3c09a3_b8552f51","line":4,"in_reply_to":"7a3c09a3_9afdf53c","updated":"2017-01-16 15:23:41.000000000","message":"Done","commit_id":"1323e6de47b4f723b81733d4c2a35c94cd0b8c52"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"5bf5c6f9d5538a0dffbf70484ac05df3fa8cfffb","unresolved":false,"context_lines":[{"line_number":2,"context_line":"features:"},{"line_number":3,"context_line":"  - The federated mapping engine now supports the ability"},{"line_number":4,"context_line":"    to map federated (shadow) users into projects within the"},{"line_number":5,"context_line":"    domain of the identity provider. This can be done"},{"line_number":6,"context_line":"    using a specific mapping syntax. This feature maintains"},{"line_number":7,"context_line":"    support for existing mappings, but adds some enhancements"},{"line_number":8,"context_line":"    to the mapping engine to enable auto-provisioning of"}],"source_content_type":"text/x-yaml","patch_set":12,"id":"7a3c09a3_e791c0f2","line":5,"updated":"2017-01-16 20:13:13.000000000","message":"I think we should be more explicit about saying projects that don\u0027t exist will be created.","commit_id":"617a3d95eabcfac21e1419fc0ca5904e832315a3"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"af1a8e665922467131482e75dde0c865094e294b","unresolved":false,"context_lines":[{"line_number":2,"context_line":"features:"},{"line_number":3,"context_line":"  - The federated mapping engine now supports the ability"},{"line_number":4,"context_line":"    to map federated (shadow) users into projects within the"},{"line_number":5,"context_line":"    domain of the identity provider. This can be done"},{"line_number":6,"context_line":"    using a specific mapping syntax. This feature maintains"},{"line_number":7,"context_line":"    support for existing mappings, but adds some enhancements"},{"line_number":8,"context_line":"    to the mapping engine to enable auto-provisioning of"}],"source_content_type":"text/x-yaml","patch_set":12,"id":"7a3c09a3_7258308b","line":5,"in_reply_to":"7a3c09a3_e791c0f2","updated":"2017-01-16 21:12:41.000000000","message":"Done","commit_id":"617a3d95eabcfac21e1419fc0ca5904e832315a3"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"d6c57cb4c453a4d4be0c72d7b83f9eca4637a1bd","unresolved":false,"context_lines":[{"line_number":1,"context_line":"---"},{"line_number":2,"context_line":"features:"},{"line_number":3,"context_line":"  - The federated mapping engine now supports the ability"},{"line_number":4,"context_line":"    to map federated (shadow) users into projects within the"},{"line_number":5,"context_line":"    domain of the identity provider. If the project within the"},{"line_number":6,"context_line":"    mapping doens\u0027t exist, it will be automatically created in"},{"line_number":7,"context_line":"    the domain of the Identity Provider. This behavior can be done"}],"source_content_type":"text/x-yaml","patch_set":13,"id":"7a3c09a3_cfe04ffd","line":4,"range":{"start_line":4,"start_character":20,"end_line":4,"end_character":30},"updated":"2017-01-17 04:07:52.000000000","message":"remove this, a user shouldn\u0027t have to know what a shadow user is","commit_id":"9f559e55393f0d47e7fb94a7eab908a8064f0763"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"56b868279987c9e5d1e42277d5fd5256dd10dee9","unresolved":false,"context_lines":[{"line_number":1,"context_line":"---"},{"line_number":2,"context_line":"features:"},{"line_number":3,"context_line":"  - The federated mapping engine now supports the ability"},{"line_number":4,"context_line":"    to map federated (shadow) users into projects within the"},{"line_number":5,"context_line":"    domain of the identity provider. If the project within the"},{"line_number":6,"context_line":"    mapping doens\u0027t exist, it will be automatically created in"},{"line_number":7,"context_line":"    the domain of the Identity Provider. This behavior can be done"}],"source_content_type":"text/x-yaml","patch_set":13,"id":"7a3c09a3_53f78f8a","line":4,"in_reply_to":"7a3c09a3_cfe04ffd","updated":"2017-01-17 15:54:21.000000000","message":"Done","commit_id":"9f559e55393f0d47e7fb94a7eab908a8064f0763"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"d6c57cb4c453a4d4be0c72d7b83f9eca4637a1bd","unresolved":false,"context_lines":[{"line_number":2,"context_line":"features:"},{"line_number":3,"context_line":"  - The federated mapping engine now supports the ability"},{"line_number":4,"context_line":"    to map federated (shadow) users into projects within the"},{"line_number":5,"context_line":"    domain of the identity provider. If the project within the"},{"line_number":6,"context_line":"    mapping doens\u0027t exist, it will be automatically created in"},{"line_number":7,"context_line":"    the domain of the Identity Provider. This behavior can be done"},{"line_number":8,"context_line":"    using a specific mapping syntax. This feature maintains"}],"source_content_type":"text/x-yaml","patch_set":13,"id":"7a3c09a3_0fced781","line":5,"range":{"start_line":5,"start_character":37,"end_line":5,"end_character":52},"updated":"2017-01-17 04:07:52.000000000","message":"project specified in the mapping*","commit_id":"9f559e55393f0d47e7fb94a7eab908a8064f0763"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"56b868279987c9e5d1e42277d5fd5256dd10dee9","unresolved":false,"context_lines":[{"line_number":2,"context_line":"features:"},{"line_number":3,"context_line":"  - The federated mapping engine now supports the ability"},{"line_number":4,"context_line":"    to map federated (shadow) users into projects within the"},{"line_number":5,"context_line":"    domain of the identity provider. If the project within the"},{"line_number":6,"context_line":"    mapping doens\u0027t exist, it will be automatically created in"},{"line_number":7,"context_line":"    the domain of the Identity Provider. This behavior can be done"},{"line_number":8,"context_line":"    using a specific mapping syntax. This feature maintains"}],"source_content_type":"text/x-yaml","patch_set":13,"id":"7a3c09a3_b37a73ef","line":5,"in_reply_to":"7a3c09a3_0fced781","updated":"2017-01-17 15:54:21.000000000","message":"Done","commit_id":"9f559e55393f0d47e7fb94a7eab908a8064f0763"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"d6c57cb4c453a4d4be0c72d7b83f9eca4637a1bd","unresolved":false,"context_lines":[{"line_number":3,"context_line":"  - The federated mapping engine now supports the ability"},{"line_number":4,"context_line":"    to map federated (shadow) users into projects within the"},{"line_number":5,"context_line":"    domain of the identity provider. If the project within the"},{"line_number":6,"context_line":"    mapping doens\u0027t exist, it will be automatically created in"},{"line_number":7,"context_line":"    the domain of the Identity Provider. This behavior can be done"},{"line_number":8,"context_line":"    using a specific mapping syntax. This feature maintains"},{"line_number":9,"context_line":"    support for existing mappings, but adds some enhancements"}],"source_content_type":"text/x-yaml","patch_set":13,"id":"7a3c09a3_6fbcbbdc","line":6,"range":{"start_line":6,"start_character":12,"end_line":6,"end_character":19},"updated":"2017-01-17 04:07:52.000000000","message":"nit: use \"does not\"","commit_id":"9f559e55393f0d47e7fb94a7eab908a8064f0763"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"56b868279987c9e5d1e42277d5fd5256dd10dee9","unresolved":false,"context_lines":[{"line_number":3,"context_line":"  - The federated mapping engine now supports the ability"},{"line_number":4,"context_line":"    to map federated (shadow) users into projects within the"},{"line_number":5,"context_line":"    domain of the identity provider. If the project within the"},{"line_number":6,"context_line":"    mapping doens\u0027t exist, it will be automatically created in"},{"line_number":7,"context_line":"    the domain of the Identity Provider. This behavior can be done"},{"line_number":8,"context_line":"    using a specific mapping syntax. This feature maintains"},{"line_number":9,"context_line":"    support for existing mappings, but adds some enhancements"}],"source_content_type":"text/x-yaml","patch_set":13,"id":"7a3c09a3_536cef34","line":6,"in_reply_to":"7a3c09a3_6fbcbbdc","updated":"2017-01-17 15:54:21.000000000","message":"Done","commit_id":"9f559e55393f0d47e7fb94a7eab908a8064f0763"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"d6c57cb4c453a4d4be0c72d7b83f9eca4637a1bd","unresolved":false,"context_lines":[{"line_number":4,"context_line":"    to map federated (shadow) users into projects within the"},{"line_number":5,"context_line":"    domain of the identity provider. If the project within the"},{"line_number":6,"context_line":"    mapping doens\u0027t exist, it will be automatically created in"},{"line_number":7,"context_line":"    the domain of the Identity Provider. This behavior can be done"},{"line_number":8,"context_line":"    using a specific mapping syntax. This feature maintains"},{"line_number":9,"context_line":"    support for existing mappings, but adds some enhancements"},{"line_number":10,"context_line":"    to the mapping engine to enable auto-provisioning of"},{"line_number":11,"context_line":"    resources in federated workflows."}],"source_content_type":"text/x-yaml","patch_set":13,"id":"7a3c09a3_4fc45f5e","line":8,"range":{"start_line":7,"start_character":40,"end_line":8,"end_character":36},"updated":"2017-01-17 04:07:52.000000000","message":"link to an example?","commit_id":"9f559e55393f0d47e7fb94a7eab908a8064f0763"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"56b868279987c9e5d1e42277d5fd5256dd10dee9","unresolved":false,"context_lines":[{"line_number":5,"context_line":"    domain of the identity provider. If the project within the"},{"line_number":6,"context_line":"    mapping doens\u0027t exist, it will be automatically created in"},{"line_number":7,"context_line":"    the domain of the Identity Provider. This behavior can be done"},{"line_number":8,"context_line":"    using a specific mapping syntax. This feature maintains"},{"line_number":9,"context_line":"    support for existing mappings, but adds some enhancements"},{"line_number":10,"context_line":"    to the mapping engine to enable auto-provisioning of"},{"line_number":11,"context_line":"    resources in federated workflows."}],"source_content_type":"text/x-yaml","patch_set":13,"id":"7a3c09a3_30f036fe","line":8,"in_reply_to":"7a3c09a3_4fc45f5e","updated":"2017-01-17 15:54:21.000000000","message":"I have to refactor the documentation to include some - I\u0027ll link to it when I get a new patch up.","commit_id":"9f559e55393f0d47e7fb94a7eab908a8064f0763"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"d6c57cb4c453a4d4be0c72d7b83f9eca4637a1bd","unresolved":false,"context_lines":[{"line_number":6,"context_line":"    mapping doens\u0027t exist, it will be automatically created in"},{"line_number":7,"context_line":"    the domain of the Identity Provider. This behavior can be done"},{"line_number":8,"context_line":"    using a specific mapping syntax. This feature maintains"},{"line_number":9,"context_line":"    support for existing mappings, but adds some enhancements"},{"line_number":10,"context_line":"    to the mapping engine to enable auto-provisioning of"},{"line_number":11,"context_line":"    resources in federated workflows."}],"source_content_type":"text/x-yaml","patch_set":13,"id":"7a3c09a3_0f95f73d","line":9,"range":{"start_line":9,"start_character":44,"end_line":9,"end_character":48},"updated":"2017-01-17 04:07:52.000000000","message":"remove \"some\"","commit_id":"9f559e55393f0d47e7fb94a7eab908a8064f0763"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"d6c57cb4c453a4d4be0c72d7b83f9eca4637a1bd","unresolved":false,"context_lines":[{"line_number":5,"context_line":"    domain of the identity provider. If the project within the"},{"line_number":6,"context_line":"    mapping doens\u0027t exist, it will be automatically created in"},{"line_number":7,"context_line":"    the domain of the Identity Provider. This behavior can be done"},{"line_number":8,"context_line":"    using a specific mapping syntax. This feature maintains"},{"line_number":9,"context_line":"    support for existing mappings, but adds some enhancements"},{"line_number":10,"context_line":"    to the mapping engine to enable auto-provisioning of"},{"line_number":11,"context_line":"    resources in federated workflows."}],"source_content_type":"text/x-yaml","patch_set":13,"id":"7a3c09a3_ef97cb45","line":9,"range":{"start_line":8,"start_character":37,"end_line":9,"end_character":33},"updated":"2017-01-17 04:07:52.000000000","message":"this is redundant, i expect us to continue supporting things","commit_id":"9f559e55393f0d47e7fb94a7eab908a8064f0763"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"56b868279987c9e5d1e42277d5fd5256dd10dee9","unresolved":false,"context_lines":[{"line_number":6,"context_line":"    mapping doens\u0027t exist, it will be automatically created in"},{"line_number":7,"context_line":"    the domain of the Identity Provider. This behavior can be done"},{"line_number":8,"context_line":"    using a specific mapping syntax. This feature maintains"},{"line_number":9,"context_line":"    support for existing mappings, but adds some enhancements"},{"line_number":10,"context_line":"    to the mapping engine to enable auto-provisioning of"},{"line_number":11,"context_line":"    resources in federated workflows."}],"source_content_type":"text/x-yaml","patch_set":13,"id":"7a3c09a3_734c8bc8","line":9,"in_reply_to":"7a3c09a3_0f95f73d","updated":"2017-01-17 15:54:21.000000000","message":"Done","commit_id":"9f559e55393f0d47e7fb94a7eab908a8064f0763"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"56b868279987c9e5d1e42277d5fd5256dd10dee9","unresolved":false,"context_lines":[{"line_number":6,"context_line":"    mapping doens\u0027t exist, it will be automatically created in"},{"line_number":7,"context_line":"    the domain of the Identity Provider. This behavior can be done"},{"line_number":8,"context_line":"    using a specific mapping syntax. This feature maintains"},{"line_number":9,"context_line":"    support for existing mappings, but adds some enhancements"},{"line_number":10,"context_line":"    to the mapping engine to enable auto-provisioning of"},{"line_number":11,"context_line":"    resources in federated workflows."}],"source_content_type":"text/x-yaml","patch_set":13,"id":"7a3c09a3_33dda3e0","line":9,"in_reply_to":"7a3c09a3_ef97cb45","updated":"2017-01-17 15:54:21.000000000","message":"I omitted the last sentence, too.","commit_id":"9f559e55393f0d47e7fb94a7eab908a8064f0763"},{"author":{"_account_id":11022,"name":"Rodrigo Duarte Sousa","email":"rodrigodsousa@gmail.com","username":"rodrigods"},"change_message_id":"5bb4a7a9c0f87c4fe087fb2e1a2b7de03e16c50c","unresolved":false,"context_lines":[{"line_number":2,"context_line":"features:"},{"line_number":3,"context_line":"  - The federated mapping engine now supports the ability"},{"line_number":4,"context_line":"    to automatically provision federated users into projects"},{"line_number":5,"context_line":"    specified in the mapping at federated login time. If the project"},{"line_number":6,"context_line":"    within the mapping does not exist, it will be automatically"},{"line_number":7,"context_line":"    created in the domain of the Identity Provider. This behavior"},{"line_number":8,"context_line":"    can be done using a specific mapping syntax."}],"source_content_type":"text/x-yaml","patch_set":15,"id":"5a3905b3_fd8e1c26","line":5,"range":{"start_line":5,"start_character":21,"end_line":5,"end_character":28},"updated":"2017-01-19 13:11:36.000000000","message":"s/mapping/mapping rules","commit_id":"4ea0a20e02dad8816e49bf6b58b595db746ca385"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"5d97540db59356d698fe7fc47ba6ffb862089224","unresolved":false,"context_lines":[{"line_number":2,"context_line":"features:"},{"line_number":3,"context_line":"  - The federated mapping engine now supports the ability"},{"line_number":4,"context_line":"    to automatically provision federated users into projects"},{"line_number":5,"context_line":"    specified in the mapping at federated login time. If the project"},{"line_number":6,"context_line":"    within the mapping does not exist, it will be automatically"},{"line_number":7,"context_line":"    created in the domain of the Identity Provider. This behavior"},{"line_number":8,"context_line":"    can be done using a specific mapping syntax."}],"source_content_type":"text/x-yaml","patch_set":15,"id":"5a3905b3_25a8821f","line":5,"in_reply_to":"5a3905b3_fd8e1c26","updated":"2017-01-19 15:16:27.000000000","message":"Done","commit_id":"4ea0a20e02dad8816e49bf6b58b595db746ca385"},{"author":{"_account_id":11022,"name":"Rodrigo Duarte Sousa","email":"rodrigodsousa@gmail.com","username":"rodrigods"},"change_message_id":"5bb4a7a9c0f87c4fe087fb2e1a2b7de03e16c50c","unresolved":false,"context_lines":[{"line_number":4,"context_line":"    to automatically provision federated users into projects"},{"line_number":5,"context_line":"    specified in the mapping at federated login time. If the project"},{"line_number":6,"context_line":"    within the mapping does not exist, it will be automatically"},{"line_number":7,"context_line":"    created in the domain of the Identity Provider. This behavior"},{"line_number":8,"context_line":"    can be done using a specific mapping syntax."}],"source_content_type":"text/x-yaml","patch_set":15,"id":"5a3905b3_1dbbe8c5","line":7,"range":{"start_line":7,"start_character":52,"end_line":7,"end_character":65},"updated":"2017-01-19 13:11:36.000000000","message":"maybe: To support this behavior, we added a specific mapping syntax.","commit_id":"4ea0a20e02dad8816e49bf6b58b595db746ca385"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"5d97540db59356d698fe7fc47ba6ffb862089224","unresolved":false,"context_lines":[{"line_number":4,"context_line":"    to automatically provision federated users into projects"},{"line_number":5,"context_line":"    specified in the mapping at federated login time. If the project"},{"line_number":6,"context_line":"    within the mapping does not exist, it will be automatically"},{"line_number":7,"context_line":"    created in the domain of the Identity Provider. This behavior"},{"line_number":8,"context_line":"    can be done using a specific mapping syntax."}],"source_content_type":"text/x-yaml","patch_set":15,"id":"5a3905b3_a00e2032","line":7,"in_reply_to":"5a3905b3_1dbbe8c5","updated":"2017-01-19 15:16:27.000000000","message":"I think that can be implied at this point. I attempted to clarify it though.","commit_id":"4ea0a20e02dad8816e49bf6b58b595db746ca385"}]}
