)]}'
{"doc/source/getting-started/policy_mapping.rst":[{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"0b2db22408a53e3aeffedb0a1f064ae233018880","unresolved":false,"context_lines":[{"line_number":223,"context_line":"identity:get_domain_config_default                         - GET /v3/domains/config/default"},{"line_number":224,"context_line":"                                                           - GET /v3/domains/config/{group}/default"},{"line_number":225,"context_line":"                                                           - GET /v3/domains/config/{group}/{option}/default"},{"line_number":226,"context_line":"identity:get_application_credential                        GET /v3/users/{user_id}/application_credentials/{application_credential_id}"},{"line_number":227,"context_line":"identity:list_application_credentials                      GET /v3/users/{user_id}/application_credentials"},{"line_number":228,"context_line":"identity:create_application_credential                     POST /v3/users/{user_id}/application_credential"},{"line_number":229,"context_line":"identity:delete_application_credential                     DELETE /v3/users/{user_id}/application_credential/{application_credential_id}"},{"line_number":230,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d  \u003d\u003d\u003d"},{"line_number":231,"context_line":""},{"line_number":232,"context_line":".. _grant_resources:"}],"source_content_type":"text/x-rst","patch_set":26,"id":"7f96bb07_c8c82076","line":229,"range":{"start_line":226,"start_character":0,"end_line":229,"end_character":136},"updated":"2018-01-10 22:30:49.000000000","message":"nit: put dashes on these to match the above","commit_id":"470538c1c5e79038bd07ec33b2a39b4a6e22eebf"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"a65e5c35e1620b8acb79898f78b9b537de71bd95","unresolved":false,"context_lines":[{"line_number":223,"context_line":"identity:get_domain_config_default                         - GET /v3/domains/config/default"},{"line_number":224,"context_line":"                                                           - GET /v3/domains/config/{group}/default"},{"line_number":225,"context_line":"                                                           - GET /v3/domains/config/{group}/{option}/default"},{"line_number":226,"context_line":"identity:get_application_credential                        GET /v3/users/{user_id}/application_credentials/{application_credential_id}"},{"line_number":227,"context_line":"identity:list_application_credentials                      GET /v3/users/{user_id}/application_credentials"},{"line_number":228,"context_line":"identity:create_application_credential                     POST /v3/users/{user_id}/application_credential"},{"line_number":229,"context_line":"identity:delete_application_credential                     DELETE /v3/users/{user_id}/application_credential/{application_credential_id}"},{"line_number":230,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d  \u003d\u003d\u003d"},{"line_number":231,"context_line":""},{"line_number":232,"context_line":".. _grant_resources:"}],"source_content_type":"text/x-rst","patch_set":26,"id":"7f96bb07_e64e60c0","line":229,"range":{"start_line":226,"start_character":0,"end_line":229,"end_character":136},"in_reply_to":"7f96bb07_c8c82076","updated":"2018-01-11 09:45:31.000000000","message":"Hmm but then that doesn\u0027t match the rest of the page","commit_id":"470538c1c5e79038bd07ec33b2a39b4a6e22eebf"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"ff7fd836d3ebf84f91a221d18e5a8b81ecfa72e3","unresolved":false,"context_lines":[{"line_number":223,"context_line":"identity:get_domain_config_default                         - GET /v3/domains/config/default"},{"line_number":224,"context_line":"                                                           - GET /v3/domains/config/{group}/default"},{"line_number":225,"context_line":"                                                           - GET /v3/domains/config/{group}/{option}/default"},{"line_number":226,"context_line":"identity:get_application_credential                        GET /v3/users/{user_id}/application_credentials/{application_credential_id}"},{"line_number":227,"context_line":"identity:list_application_credentials                      GET /v3/users/{user_id}/application_credentials"},{"line_number":228,"context_line":"identity:create_application_credential                     POST /v3/users/{user_id}/application_credential"},{"line_number":229,"context_line":"identity:delete_application_credential                     DELETE /v3/users/{user_id}/application_credential/{application_credential_id}"},{"line_number":230,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d  \u003d\u003d\u003d"},{"line_number":231,"context_line":""},{"line_number":232,"context_line":".. _grant_resources:"}],"source_content_type":"text/x-rst","patch_set":26,"id":"7f96bb07_9d1246b1","line":229,"range":{"start_line":226,"start_character":0,"end_line":229,"end_character":136},"in_reply_to":"7f96bb07_e64e60c0","updated":"2018-01-11 15:48:17.000000000","message":"Oh, I didn\u0027t expand the above, never mind then!","commit_id":"470538c1c5e79038bd07ec33b2a39b4a6e22eebf"}],"keystone/application_credential/controllers.py":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"f8584b98d898d2b6daa79742e7656460bd78c536","unresolved":false,"context_lines":[{"line_number":39,"context_line":"        \u0027expires_at\u0027,"},{"line_number":40,"context_line":"        \u0027project_id\u0027,"},{"line_number":41,"context_line":"        \u0027roles\u0027,"},{"line_number":42,"context_line":"        # secret is only expose after create, it is not stored"},{"line_number":43,"context_line":"        \u0027secret\u0027,"},{"line_number":44,"context_line":"        \u0027allow_application_credential_creation\u0027"},{"line_number":45,"context_line":"    ])"}],"source_content_type":"text/x-python","patch_set":15,"id":"9f91af0f_ae70d4a6","line":42,"range":{"start_line":42,"start_character":25,"end_line":42,"end_character":31},"updated":"2018-01-05 21:32:24.000000000","message":"exposed*?","commit_id":"9ea86466c4e39a20bc1bb82880fae8344b176265"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"f8584b98d898d2b6daa79742e7656460bd78c536","unresolved":false,"context_lines":[{"line_number":81,"context_line":"                       \"user\")"},{"line_number":82,"context_line":"            raise exception.ForbiddenAction(action\u003daction)"},{"line_number":83,"context_line":"        project_id \u003d request.context.project_id"},{"line_number":84,"context_line":"        if not project_id:"},{"line_number":85,"context_line":"            action \u003d _(\"Must be scoped to a project to create an application \""},{"line_number":86,"context_line":"                       \"credential\")"},{"line_number":87,"context_line":"            raise exception.ForbiddenAction(action\u003daction)"},{"line_number":88,"context_line":"        app_cred \u003d self._assign_unique_id(application_credential)"},{"line_number":89,"context_line":"        if not app_cred.get(\u0027secret\u0027):"},{"line_number":90,"context_line":"            app_cred[\u0027secret\u0027] \u003d self._generate_secret()"}],"source_content_type":"text/x-python","patch_set":15,"id":"9f91af0f_6e988cbf","line":87,"range":{"start_line":84,"start_character":8,"end_line":87,"end_character":58},"updated":"2018-01-05 21:32:24.000000000","message":"Not to confuse things more... but what happens if I want to create a system scope application credential?","commit_id":"9ea86466c4e39a20bc1bb82880fae8344b176265"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"1446e493b24a5dd18c1a1c56d1f9c69d79ef6ef1","unresolved":false,"context_lines":[{"line_number":62,"context_line":"    def _generate_secret(self):"},{"line_number":63,"context_line":"        length \u003d 64"},{"line_number":64,"context_line":"        secret \u003d os.urandom(length)"},{"line_number":65,"context_line":"        secret \u003d base64.urlsafe_b64encode(secret)[:-2]"},{"line_number":66,"context_line":"        secret \u003d secret.decode(\u0027utf-8\u0027)"},{"line_number":67,"context_line":"        return secret"},{"line_number":68,"context_line":""}],"source_content_type":"text/x-python","patch_set":26,"id":"7f96bb07_fca905df","line":65,"range":{"start_line":65,"start_character":49,"end_line":65,"end_character":54},"updated":"2018-01-11 22:40:29.000000000","message":"With length of 64, padding is always going to be 2, right?","commit_id":"470538c1c5e79038bd07ec33b2a39b4a6e22eebf"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"7ae7948b37f80e43db038bdd0dac4e8dac6cddb1","unresolved":false,"context_lines":[{"line_number":62,"context_line":"    def _generate_secret(self):"},{"line_number":63,"context_line":"        length \u003d 64"},{"line_number":64,"context_line":"        secret \u003d os.urandom(length)"},{"line_number":65,"context_line":"        secret \u003d base64.urlsafe_b64encode(secret)[:-2]"},{"line_number":66,"context_line":"        secret \u003d secret.decode(\u0027utf-8\u0027)"},{"line_number":67,"context_line":"        return secret"},{"line_number":68,"context_line":""}],"source_content_type":"text/x-python","patch_set":26,"id":"7f96bb07_79b96be7","line":65,"range":{"start_line":65,"start_character":49,"end_line":65,"end_character":54},"in_reply_to":"7f96bb07_563b1cea","updated":"2018-01-12 15:25:29.000000000","message":"All good points - but +1 for consistency.","commit_id":"470538c1c5e79038bd07ec33b2a39b4a6e22eebf"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"477529dfddd5ad92bbff88838c041c7dd45dde24","unresolved":false,"context_lines":[{"line_number":62,"context_line":"    def _generate_secret(self):"},{"line_number":63,"context_line":"        length \u003d 64"},{"line_number":64,"context_line":"        secret \u003d os.urandom(length)"},{"line_number":65,"context_line":"        secret \u003d base64.urlsafe_b64encode(secret)[:-2]"},{"line_number":66,"context_line":"        secret \u003d secret.decode(\u0027utf-8\u0027)"},{"line_number":67,"context_line":"        return secret"},{"line_number":68,"context_line":""}],"source_content_type":"text/x-python","patch_set":26,"id":"7f96bb07_563b1cea","line":65,"range":{"start_line":65,"start_character":49,"end_line":65,"end_character":54},"in_reply_to":"7f96bb07_761178ac","updated":"2018-01-12 15:10:21.000000000","message":"I took this from http://git.openstack.org/cgit/openstack/keystone/tree/keystone/token/providers/common.py#n62 but rstrip works just as well, will change it.\n\nI think the padding isn\u0027t url-safe because \u003d is used for query parameters, e.g. GET /v3/users?name\u003dcmurphy\n\nWe\u0027re not actually using this in a url ourselves and probably no one should send an application secret as part of a url. I\u0027m not really totally sure we need to strip the padding for tokens since as of v3 they\u0027re only sent as headers, not part of a url. But in any case it looks kind of weird to me to keep the padding and we don\u0027t need it for anything since we\u0027re not going to decode it.","commit_id":"470538c1c5e79038bd07ec33b2a39b4a6e22eebf"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"5fe87eb3e21cef7a636b5989c3a317b2c6e5ff22","unresolved":false,"context_lines":[{"line_number":62,"context_line":"    def _generate_secret(self):"},{"line_number":63,"context_line":"        length \u003d 64"},{"line_number":64,"context_line":"        secret \u003d os.urandom(length)"},{"line_number":65,"context_line":"        secret \u003d base64.urlsafe_b64encode(secret)[:-2]"},{"line_number":66,"context_line":"        secret \u003d secret.decode(\u0027utf-8\u0027)"},{"line_number":67,"context_line":"        return secret"},{"line_number":68,"context_line":""}],"source_content_type":"text/x-python","patch_set":26,"id":"7f96bb07_761178ac","line":65,"range":{"start_line":65,"start_character":49,"end_line":65,"end_character":54},"in_reply_to":"7f96bb07_b03b8bcf","updated":"2018-01-12 15:00:23.000000000","message":"Something like this might be safer: \n\nhttps://github.com/openstack/keystone/blob/master/keystone/token/providers/fernet/token_formatters.py#L78-L79\n\nBecause tokens are variable length, the padding can also fluctuate. Since we\u0027re dealing with a fixed length we probably don\u0027t have to worry about it as much, but from the comment it doesn\u0027t look like padding is url-safe (I\u0027d need to dig up real references).","commit_id":"470538c1c5e79038bd07ec33b2a39b4a6e22eebf"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"24dafc34ac15a5578ac8d4be77d5496794c134e9","unresolved":false,"context_lines":[{"line_number":62,"context_line":"    def _generate_secret(self):"},{"line_number":63,"context_line":"        length \u003d 64"},{"line_number":64,"context_line":"        secret \u003d os.urandom(length)"},{"line_number":65,"context_line":"        secret \u003d base64.urlsafe_b64encode(secret)[:-2]"},{"line_number":66,"context_line":"        secret \u003d secret.decode(\u0027utf-8\u0027)"},{"line_number":67,"context_line":"        return secret"},{"line_number":68,"context_line":""}],"source_content_type":"text/x-python","patch_set":26,"id":"7f96bb07_b03b8bcf","line":65,"range":{"start_line":65,"start_character":49,"end_line":65,"end_character":54},"in_reply_to":"7f96bb07_fca905df","updated":"2018-01-12 11:09:28.000000000","message":"Yes - will add a comment. Also open to suggestions on what the right length should really be. I guess I could make it 66 bytes and then not chop the padding.","commit_id":"470538c1c5e79038bd07ec33b2a39b4a6e22eebf"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"1446e493b24a5dd18c1a1c56d1f9c69d79ef6ef1","unresolved":false,"context_lines":[{"line_number":95,"context_line":"            raise exception.ForbiddenAction(action\u003daction)"},{"line_number":96,"context_line":"        app_cred \u003d self._assign_unique_id(application_credential)"},{"line_number":97,"context_line":"        if not app_cred.get(\u0027secret\u0027):"},{"line_number":98,"context_line":"            app_cred[\u0027secret\u0027] \u003d self._generate_secret()"},{"line_number":99,"context_line":"        app_cred[\u0027user_id\u0027] \u003d user_id"},{"line_number":100,"context_line":"        app_cred[\u0027project_id\u0027] \u003d project_id"},{"line_number":101,"context_line":"        app_cred[\u0027roles\u0027] \u003d self._normalize_role_list(app_cred[\u0027roles\u0027])"}],"source_content_type":"text/x-python","patch_set":26,"id":"7f96bb07_1cd2b15d","line":98,"updated":"2018-01-11 22:40:29.000000000","message":"If a secret isn\u0027t provided and keystone generates it, it is url-safe. It makes sense to validate user-provided secrets the same way, right?","commit_id":"470538c1c5e79038bd07ec33b2a39b4a6e22eebf"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"24dafc34ac15a5578ac8d4be77d5496794c134e9","unresolved":false,"context_lines":[{"line_number":95,"context_line":"            raise exception.ForbiddenAction(action\u003daction)"},{"line_number":96,"context_line":"        app_cred \u003d self._assign_unique_id(application_credential)"},{"line_number":97,"context_line":"        if not app_cred.get(\u0027secret\u0027):"},{"line_number":98,"context_line":"            app_cred[\u0027secret\u0027] \u003d self._generate_secret()"},{"line_number":99,"context_line":"        app_cred[\u0027user_id\u0027] \u003d user_id"},{"line_number":100,"context_line":"        app_cred[\u0027project_id\u0027] \u003d project_id"},{"line_number":101,"context_line":"        app_cred[\u0027roles\u0027] \u003d self._normalize_role_list(app_cred[\u0027roles\u0027])"}],"source_content_type":"text/x-python","patch_set":26,"id":"7f96bb07_90320ff1","line":98,"in_reply_to":"7f96bb07_1cd2b15d","updated":"2018-01-12 11:09:28.000000000","message":"Good point","commit_id":"470538c1c5e79038bd07ec33b2a39b4a6e22eebf"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"f78b9c50b7bd920bc6ef615c5b2d1a3eb40b7f15","unresolved":false,"context_lines":[{"line_number":95,"context_line":"            raise exception.ForbiddenAction(action\u003daction)"},{"line_number":96,"context_line":"        app_cred \u003d self._assign_unique_id(application_credential)"},{"line_number":97,"context_line":"        if not app_cred.get(\u0027secret\u0027):"},{"line_number":98,"context_line":"            app_cred[\u0027secret\u0027] \u003d self._generate_secret()"},{"line_number":99,"context_line":"        app_cred[\u0027user_id\u0027] \u003d user_id"},{"line_number":100,"context_line":"        app_cred[\u0027project_id\u0027] \u003d project_id"},{"line_number":101,"context_line":"        app_cred[\u0027roles\u0027] \u003d self._normalize_role_list(app_cred[\u0027roles\u0027])"}],"source_content_type":"text/x-python","patch_set":26,"id":"7f96bb07_366a05b3","line":98,"in_reply_to":"7f96bb07_90320ff1","updated":"2018-01-12 22:31:03.000000000","message":"Actually no, it\u0027s probably not a good idea to change the secret behind the user\u0027s back, for the same reason we can\u0027t manipulate their passwords.","commit_id":"470538c1c5e79038bd07ec33b2a39b4a6e22eebf"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"0b2db22408a53e3aeffedb0a1f064ae233018880","unresolved":false,"context_lines":[{"line_number":99,"context_line":"        app_cred[\u0027user_id\u0027] \u003d user_id"},{"line_number":100,"context_line":"        app_cred[\u0027project_id\u0027] \u003d project_id"},{"line_number":101,"context_line":"        app_cred[\u0027roles\u0027] \u003d self._normalize_role_list(app_cred[\u0027roles\u0027])"},{"line_number":102,"context_line":"        if app_cred.get(\u0027expires_at\u0027):"},{"line_number":103,"context_line":"            app_cred[\u0027expires_at\u0027] \u003d utils.parse_expiration_date("},{"line_number":104,"context_line":"                app_cred[\u0027expires_at\u0027])"},{"line_number":105,"context_line":"        app_cred \u003d self._normalize_dict(app_cred)"},{"line_number":106,"context_line":"        app_cred_api \u003d PROVIDERS.application_credential_api"},{"line_number":107,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":26,"id":"7f96bb07_db4b0cae","line":104,"range":{"start_line":102,"start_character":8,"end_line":104,"end_character":39},"updated":"2018-01-10 22:30:49.000000000","message":"I left a comment in another PS but are we allowing users to create already expired application credentials?","commit_id":"470538c1c5e79038bd07ec33b2a39b4a6e22eebf"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"a65e5c35e1620b8acb79898f78b9b537de71bd95","unresolved":false,"context_lines":[{"line_number":99,"context_line":"        app_cred[\u0027user_id\u0027] \u003d user_id"},{"line_number":100,"context_line":"        app_cred[\u0027project_id\u0027] \u003d project_id"},{"line_number":101,"context_line":"        app_cred[\u0027roles\u0027] \u003d self._normalize_role_list(app_cred[\u0027roles\u0027])"},{"line_number":102,"context_line":"        if app_cred.get(\u0027expires_at\u0027):"},{"line_number":103,"context_line":"            app_cred[\u0027expires_at\u0027] \u003d utils.parse_expiration_date("},{"line_number":104,"context_line":"                app_cred[\u0027expires_at\u0027])"},{"line_number":105,"context_line":"        app_cred \u003d self._normalize_dict(app_cred)"},{"line_number":106,"context_line":"        app_cred_api \u003d PROVIDERS.application_credential_api"},{"line_number":107,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":26,"id":"7f96bb07_4685d4ac","line":104,"range":{"start_line":102,"start_character":8,"end_line":104,"end_character":39},"in_reply_to":"7f96bb07_db4b0cae","updated":"2018-01-11 09:45:31.000000000","message":"It\u0027s possible using the manager API, but this parse_expiration_date method validates that the date is in the future.","commit_id":"470538c1c5e79038bd07ec33b2a39b4a6e22eebf"},{"author":{"_account_id":15054,"name":"wangxiyuan","email":"wangxiyuan1007@gmail.com","username":"wangxiyuan"},"change_message_id":"6ecfc0a92a18e84d4f89168b1f7127bec6b42134","unresolved":false,"context_lines":[{"line_number":98,"context_line":"            app_cred[\u0027secret\u0027] \u003d self._generate_secret()"},{"line_number":99,"context_line":"        app_cred[\u0027user_id\u0027] \u003d user_id"},{"line_number":100,"context_line":"        app_cred[\u0027project_id\u0027] \u003d project_id"},{"line_number":101,"context_line":"        app_cred[\u0027roles\u0027] \u003d self._normalize_role_list(app_cred[\u0027roles\u0027])"},{"line_number":102,"context_line":"        if app_cred.get(\u0027expires_at\u0027):"},{"line_number":103,"context_line":"            app_cred[\u0027expires_at\u0027] \u003d utils.parse_expiration_date("},{"line_number":104,"context_line":"                app_cred[\u0027expires_at\u0027])"}],"source_content_type":"text/x-python","patch_set":27,"id":"7f96bb07_9347871e","line":101,"range":{"start_line":101,"start_character":54,"end_line":101,"end_character":71},"updated":"2018-01-12 02:51:36.000000000","message":"doess \"roles\" is required? If so, it should be limited by schema, if not, we should use app_cred.get(\u0027roles\u0027), otherwise 500 error will occur if there is no \"roles\" in the request body.","commit_id":"3ed9be995bc5dba2ec7803504287d6f74403a80b"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"24dafc34ac15a5578ac8d4be77d5496794c134e9","unresolved":false,"context_lines":[{"line_number":98,"context_line":"            app_cred[\u0027secret\u0027] \u003d self._generate_secret()"},{"line_number":99,"context_line":"        app_cred[\u0027user_id\u0027] \u003d user_id"},{"line_number":100,"context_line":"        app_cred[\u0027project_id\u0027] \u003d project_id"},{"line_number":101,"context_line":"        app_cred[\u0027roles\u0027] \u003d self._normalize_role_list(app_cred[\u0027roles\u0027])"},{"line_number":102,"context_line":"        if app_cred.get(\u0027expires_at\u0027):"},{"line_number":103,"context_line":"            app_cred[\u0027expires_at\u0027] \u003d utils.parse_expiration_date("},{"line_number":104,"context_line":"                app_cred[\u0027expires_at\u0027])"}],"source_content_type":"text/x-python","patch_set":27,"id":"7f96bb07_90b52f34","line":101,"range":{"start_line":101,"start_character":54,"end_line":101,"end_character":71},"in_reply_to":"7f96bb07_9347871e","updated":"2018-01-12 11:09:28.000000000","message":"Good point, it should be possible to give an empty list of roles so this should use .get","commit_id":"3ed9be995bc5dba2ec7803504287d6f74403a80b"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"0e122cee1a0ca7be36f96ecacc31f79026f2ec2e","unresolved":false,"context_lines":[{"line_number":115,"context_line":"        except exception.RoleAssignmentNotFound as e:"},{"line_number":116,"context_line":"            # Raise a Bad Request, not a Not Found, in accordance with the"},{"line_number":117,"context_line":"            # API-SIG recommendations:"},{"line_number":118,"context_line":"            # https://specs.openstack.org/openstack/api-wg/guidelines/http.html#failure-code-clarifications"},{"line_number":119,"context_line":"            raise exception.ApplicationCredentialValidationError("},{"line_number":120,"context_line":"                detail\u003dstr(e))"},{"line_number":121,"context_line":"        return ApplicationCredentialV3.wrap_member(request.context_dict, ref)"}],"source_content_type":"text/x-python","patch_set":33,"id":"7f96bb07_fb15eb49","line":118,"updated":"2018-01-17 20:55:45.000000000","message":"I spent way too much time trying to find this the other day... bookmarking!","commit_id":"d823c402758635f967aa1025e43e90c281221a61"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"1f80550fa813970a4e0563749059fc0d638b1795","unresolved":false,"context_lines":[{"line_number":98,"context_line":"        project_id \u003d request.context.project_id"},{"line_number":99,"context_line":"        app_cred \u003d self._assign_unique_id(application_credential)"},{"line_number":100,"context_line":"        if not app_cred.get(\u0027secret\u0027):"},{"line_number":101,"context_line":"            app_cred[\u0027secret\u0027] \u003d self._generate_secret()"},{"line_number":102,"context_line":"        app_cred[\u0027user_id\u0027] \u003d user_id"},{"line_number":103,"context_line":"        app_cred[\u0027project_id\u0027] \u003d project_id"},{"line_number":104,"context_line":"        app_cred[\u0027roles\u0027] \u003d self._normalize_role_list("}],"source_content_type":"text/x-python","patch_set":34,"id":"7f96bb07_78ba17c1","line":101,"updated":"2018-01-18 19:18:14.000000000","message":"Don\u0027t we still want to make the secret url safe if we do that for generated ones?","commit_id":"375e80c471e2fdd1ced5517bf2bc43bc92477670"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"ea9feebf1c1477fde09e089d5351a45ba2f8fa06","unresolved":false,"context_lines":[{"line_number":98,"context_line":"        project_id \u003d request.context.project_id"},{"line_number":99,"context_line":"        app_cred \u003d self._assign_unique_id(application_credential)"},{"line_number":100,"context_line":"        if not app_cred.get(\u0027secret\u0027):"},{"line_number":101,"context_line":"            app_cred[\u0027secret\u0027] \u003d self._generate_secret()"},{"line_number":102,"context_line":"        app_cred[\u0027user_id\u0027] \u003d user_id"},{"line_number":103,"context_line":"        app_cred[\u0027project_id\u0027] \u003d project_id"},{"line_number":104,"context_line":"        app_cred[\u0027roles\u0027] \u003d self._normalize_role_list("}],"source_content_type":"text/x-python","patch_set":34,"id":"7f96bb07_9beefd1f","line":101,"in_reply_to":"7f96bb07_78ba17c1","updated":"2018-01-18 19:35:39.000000000","message":"What exactly do you propose we do to make that happen? I\u0027m very hesitant to do anything to change the input and cause the result to be something unexpected.\n\nWe don\u0027t manipulate passwords afaict, so we shouldn\u0027t change the secret if it\u0027s provided.","commit_id":"375e80c471e2fdd1ced5517bf2bc43bc92477670"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"109aec35d963ca19ca3e2bb65b9aaf8dba6f5a9f","unresolved":false,"context_lines":[{"line_number":98,"context_line":"        project_id \u003d request.context.project_id"},{"line_number":99,"context_line":"        app_cred \u003d self._assign_unique_id(application_credential)"},{"line_number":100,"context_line":"        if not app_cred.get(\u0027secret\u0027):"},{"line_number":101,"context_line":"            app_cred[\u0027secret\u0027] \u003d self._generate_secret()"},{"line_number":102,"context_line":"        app_cred[\u0027user_id\u0027] \u003d user_id"},{"line_number":103,"context_line":"        app_cred[\u0027project_id\u0027] \u003d project_id"},{"line_number":104,"context_line":"        app_cred[\u0027roles\u0027] \u003d self._normalize_role_list("}],"source_content_type":"text/x-python","patch_set":34,"id":"7f96bb07_feb04f45","line":101,"in_reply_to":"7f96bb07_9beefd1f","updated":"2018-01-18 20:03:56.000000000","message":"Ok - that\u0027s fair. I was thinking about it from the perspective of consistency of how we handle secrets regardless of where they come from, but maybe that\u0027s not important here. If a secret is generated from keystone, it\u0027ll be url-encoded.","commit_id":"375e80c471e2fdd1ced5517bf2bc43bc92477670"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"079def199201e010540068afa55f35fd50beb093","unresolved":false,"context_lines":[{"line_number":98,"context_line":"        project_id \u003d request.context.project_id"},{"line_number":99,"context_line":"        app_cred \u003d self._assign_unique_id(application_credential)"},{"line_number":100,"context_line":"        if not app_cred.get(\u0027secret\u0027):"},{"line_number":101,"context_line":"            app_cred[\u0027secret\u0027] \u003d self._generate_secret()"},{"line_number":102,"context_line":"        app_cred[\u0027user_id\u0027] \u003d user_id"},{"line_number":103,"context_line":"        app_cred[\u0027project_id\u0027] \u003d project_id"},{"line_number":104,"context_line":"        app_cred[\u0027roles\u0027] \u003d self._normalize_role_list("}],"source_content_type":"text/x-python","patch_set":34,"id":"7f96bb07_a17e26e1","line":101,"in_reply_to":"7f96bb07_feb04f45","updated":"2018-01-18 21:56:04.000000000","message":"I would say don\u0027t edit the secret if a user provides it, similar to passwords.","commit_id":"375e80c471e2fdd1ced5517bf2bc43bc92477670"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"8d40f756ae63a51df041667e261f5c3b1c4807da","unresolved":false,"context_lines":[{"line_number":84,"context_line":"        return {cls.member_name: ref}"},{"line_number":85,"context_line":""},{"line_number":86,"context_line":"    @controller.protected()"},{"line_number":87,"context_line":"    def create_application_credential(self, request, user_id,"},{"line_number":88,"context_line":"                                      application_credential):"},{"line_number":89,"context_line":"        validation.lazy_validate(schema.application_credential_create,"},{"line_number":90,"context_line":"                                 application_credential)"}],"source_content_type":"text/x-python","patch_set":37,"id":"7f96bb07_0d18287f","line":87,"range":{"start_line":87,"start_character":8,"end_line":87,"end_character":37},"updated":"2018-01-22 15:07:16.000000000","message":"When we talked about application credentials back in Denver, we mentioned giving them a limit (e.g. I can only create 5 application credentials).\n\nWhere do we want to do that kind of enforcement?","commit_id":"f29a5a8d12eb6e048d2966b31ec8635a6165cbd7"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"0f55faeadb188dfb0b84c1d14e1f76dc0f1198df","unresolved":false,"context_lines":[{"line_number":84,"context_line":"        return {cls.member_name: ref}"},{"line_number":85,"context_line":""},{"line_number":86,"context_line":"    @controller.protected()"},{"line_number":87,"context_line":"    def create_application_credential(self, request, user_id,"},{"line_number":88,"context_line":"                                      application_credential):"},{"line_number":89,"context_line":"        validation.lazy_validate(schema.application_credential_create,"},{"line_number":90,"context_line":"                                 application_credential)"}],"source_content_type":"text/x-python","patch_set":37,"id":"7f96bb07_20a63b55","line":87,"range":{"start_line":87,"start_character":8,"end_line":87,"end_character":37},"in_reply_to":"7f96bb07_0d18287f","updated":"2018-01-22 23:30:20.000000000","message":"This is being addressed here - https://review.openstack.org/#/c/536543/3","commit_id":"f29a5a8d12eb6e048d2966b31ec8635a6165cbd7"},{"author":{"_account_id":11589,"name":"Harry Rybacki","email":"hrybacki@redhat.com","username":"hrybacki"},"change_message_id":"ea35138f777d8f51f5310a4bc2d988f15a85f601","unresolved":false,"context_lines":[{"line_number":44,"context_line":"        \u0027expires_at\u0027,"},{"line_number":45,"context_line":"        \u0027project_id\u0027,"},{"line_number":46,"context_line":"        \u0027roles\u0027,"},{"line_number":47,"context_line":"        # secret is only expose after create, it is not stored"},{"line_number":48,"context_line":"        \u0027secret\u0027,"},{"line_number":49,"context_line":"        \u0027links\u0027,"},{"line_number":50,"context_line":"        \u0027unrestricted\u0027"}],"source_content_type":"text/x-python","patch_set":39,"id":"7f96bb07_baf49a88","line":47,"range":{"start_line":47,"start_character":25,"end_line":47,"end_character":31},"updated":"2018-01-23 20:27:28.000000000","message":"nit: exposed","commit_id":"31de309683e71ad1a98cc09ea7afe877e7ef8a28"}],"keystone/application_credential/routers.py":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"1446e493b24a5dd18c1a1c56d1f9c69d79ef6ef1","unresolved":false,"context_lines":[{"line_number":11,"context_line":"# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the"},{"line_number":12,"context_line":"# License for the specific language governing permissions and limitations"},{"line_number":13,"context_line":"# under the License."},{"line_number":14,"context_line":"\"\"\"WSGI Routers for the Identity service.\"\"\""},{"line_number":15,"context_line":""},{"line_number":16,"context_line":"from keystone.application_credential import controllers"},{"line_number":17,"context_line":"from keystone.common import json_home"}],"source_content_type":"text/x-python","patch_set":26,"id":"7f96bb07_31c316f0","line":14,"range":{"start_line":14,"start_character":24,"end_line":14,"end_character":32},"updated":"2018-01-11 22:40:29.000000000","message":"Copy/paste from https://github.com/openstack/keystone/blob/master/keystone/identity/routers.py#L14 ?","commit_id":"470538c1c5e79038bd07ec33b2a39b4a6e22eebf"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"24dafc34ac15a5578ac8d4be77d5496794c134e9","unresolved":false,"context_lines":[{"line_number":11,"context_line":"# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the"},{"line_number":12,"context_line":"# License for the specific language governing permissions and limitations"},{"line_number":13,"context_line":"# under the License."},{"line_number":14,"context_line":"\"\"\"WSGI Routers for the Identity service.\"\"\""},{"line_number":15,"context_line":""},{"line_number":16,"context_line":"from keystone.application_credential import controllers"},{"line_number":17,"context_line":"from keystone.common import json_home"}],"source_content_type":"text/x-python","patch_set":26,"id":"7f96bb07_50524715","line":14,"range":{"start_line":14,"start_character":24,"end_line":14,"end_character":32},"in_reply_to":"7f96bb07_31c316f0","updated":"2018-01-12 11:09:28.000000000","message":"yup","commit_id":"470538c1c5e79038bd07ec33b2a39b4a6e22eebf"}],"keystone/application_credential/schema.py":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"0e122cee1a0ca7be36f96ecacc31f79026f2ec2e","unresolved":false,"context_lines":[{"line_number":24,"context_line":"            \u0027name\u0027: parameter_types.name"},{"line_number":25,"context_line":"        },"},{"line_number":26,"context_line":"        \u0027minProperties\u0027: 1,"},{"line_number":27,"context_line":"        \u0027maxProperties\u0027: 1,"},{"line_number":28,"context_line":"        \u0027additionalProperties\u0027: False"},{"line_number":29,"context_line":"    }"},{"line_number":30,"context_line":"}"}],"source_content_type":"text/x-python","patch_set":33,"id":"7f96bb07_8df7ca59","line":27,"range":{"start_line":27,"start_character":9,"end_line":27,"end_character":22},"updated":"2018-01-17 20:55:45.000000000","message":"We\u0027re only going to allow a single role for an application credential? What about if I have multiple roles in the token I use to create an application credential?","commit_id":"d823c402758635f967aa1025e43e90c281221a61"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"672faa4b01be4400cf470f3c2ec48f385c5e6b68","unresolved":false,"context_lines":[{"line_number":24,"context_line":"            \u0027name\u0027: parameter_types.name"},{"line_number":25,"context_line":"        },"},{"line_number":26,"context_line":"        \u0027minProperties\u0027: 1,"},{"line_number":27,"context_line":"        \u0027maxProperties\u0027: 1,"},{"line_number":28,"context_line":"        \u0027additionalProperties\u0027: False"},{"line_number":29,"context_line":"    }"},{"line_number":30,"context_line":"}"}],"source_content_type":"text/x-python","patch_set":33,"id":"7f96bb07_43f67165","line":27,"range":{"start_line":27,"start_character":9,"end_line":27,"end_character":22},"in_reply_to":"7f96bb07_636ccd9b","updated":"2018-01-17 21:42:43.000000000","message":"Aha - nevermind. Thanks!","commit_id":"d823c402758635f967aa1025e43e90c281221a61"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"0deb5492d27ee0b1c3785ac816b8a53190e4390d","unresolved":false,"context_lines":[{"line_number":24,"context_line":"            \u0027name\u0027: parameter_types.name"},{"line_number":25,"context_line":"        },"},{"line_number":26,"context_line":"        \u0027minProperties\u0027: 1,"},{"line_number":27,"context_line":"        \u0027maxProperties\u0027: 1,"},{"line_number":28,"context_line":"        \u0027additionalProperties\u0027: False"},{"line_number":29,"context_line":"    }"},{"line_number":30,"context_line":"}"}],"source_content_type":"text/x-python","patch_set":33,"id":"7f96bb07_636ccd9b","line":27,"range":{"start_line":27,"start_character":9,"end_line":27,"end_character":22},"in_reply_to":"7f96bb07_8316b948","updated":"2018-01-17 21:32:00.000000000","message":"Gage is correct. If we allowed specifying both id and name then we\u0027d have to either pick one to use or validate that they matched.","commit_id":"d823c402758635f967aa1025e43e90c281221a61"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"466931f5b31525d5f4c762c1ba03823954f7eae8","unresolved":false,"context_lines":[{"line_number":24,"context_line":"            \u0027name\u0027: parameter_types.name"},{"line_number":25,"context_line":"        },"},{"line_number":26,"context_line":"        \u0027minProperties\u0027: 1,"},{"line_number":27,"context_line":"        \u0027maxProperties\u0027: 1,"},{"line_number":28,"context_line":"        \u0027additionalProperties\u0027: False"},{"line_number":29,"context_line":"    }"},{"line_number":30,"context_line":"}"}],"source_content_type":"text/x-python","patch_set":33,"id":"7f96bb07_8316b948","line":27,"range":{"start_line":27,"start_character":9,"end_line":27,"end_character":22},"in_reply_to":"7f96bb07_8df7ca59","updated":"2018-01-17 21:05:26.000000000","message":"I think this is for the properties of a \"role\" object, you can only either specify name or id. This should allow for multiple \"role\" objects.","commit_id":"d823c402758635f967aa1025e43e90c281221a61"}],"keystone/common/policies/application_credential.py":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"1446e493b24a5dd18c1a1c56d1f9c69d79ef6ef1","unresolved":false,"context_lines":[{"line_number":20,"context_line":"application_credential_policies \u003d ["},{"line_number":21,"context_line":"    policy.DocumentedRuleDefault("},{"line_number":22,"context_line":"        name\u003dbase.IDENTITY % \u0027get_application_credential\u0027,"},{"line_number":23,"context_line":"        check_str\u003dbase.RULE_ADMIN_OR_OWNER,"},{"line_number":24,"context_line":"        description\u003d\u0027Show application credential details.\u0027,"},{"line_number":25,"context_line":"        operations\u003d[{\u0027path\u0027: resource_path,"},{"line_number":26,"context_line":"                     \u0027method\u0027: \u0027GET\u0027},"}],"source_content_type":"text/x-python","patch_set":26,"id":"7f96bb07_11637a1c","line":23,"updated":"2018-01-11 22:40:29.000000000","message":"We could add scope_types for these since oslo.policy supports it.","commit_id":"470538c1c5e79038bd07ec33b2a39b4a6e22eebf"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"24dafc34ac15a5578ac8d4be77d5496794c134e9","unresolved":false,"context_lines":[{"line_number":20,"context_line":"application_credential_policies \u003d ["},{"line_number":21,"context_line":"    policy.DocumentedRuleDefault("},{"line_number":22,"context_line":"        name\u003dbase.IDENTITY % \u0027get_application_credential\u0027,"},{"line_number":23,"context_line":"        check_str\u003dbase.RULE_ADMIN_OR_OWNER,"},{"line_number":24,"context_line":"        description\u003d\u0027Show application credential details.\u0027,"},{"line_number":25,"context_line":"        operations\u003d[{\u0027path\u0027: resource_path,"},{"line_number":26,"context_line":"                     \u0027method\u0027: \u0027GET\u0027},"}],"source_content_type":"text/x-python","patch_set":26,"id":"7f96bb07_90476f4c","line":23,"in_reply_to":"7f96bb07_11637a1c","updated":"2018-01-12 11:09:28.000000000","message":"++","commit_id":"470538c1c5e79038bd07ec33b2a39b4a6e22eebf"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"0e122cee1a0ca7be36f96ecacc31f79026f2ec2e","unresolved":false,"context_lines":[{"line_number":21,"context_line":"    policy.DocumentedRuleDefault("},{"line_number":22,"context_line":"        name\u003dbase.IDENTITY % \u0027get_application_credential\u0027,"},{"line_number":23,"context_line":"        check_str\u003dbase.RULE_ADMIN_OR_OWNER,"},{"line_number":24,"context_line":"        scope_types\u003d[\u0027system\u0027, \u0027project\u0027],"},{"line_number":25,"context_line":"        description\u003d\u0027Show application credential details.\u0027,"},{"line_number":26,"context_line":"        operations\u003d[{\u0027path\u0027: resource_path,"},{"line_number":27,"context_line":"                     \u0027method\u0027: \u0027GET\u0027},"}],"source_content_type":"text/x-python","patch_set":33,"id":"7f96bb07_8d282a97","line":24,"range":{"start_line":24,"start_character":8,"end_line":24,"end_character":19},"updated":"2018-01-17 20:55:45.000000000","message":"For system administrators - they should be able to get any application credential? But for project administrators, they should only be able to get application credentials for the project they are an administrator on.\n\nJust making a note about that here so that we can follow this up with a FIXME for later.","commit_id":"d823c402758635f967aa1025e43e90c281221a61"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"0deb5492d27ee0b1c3785ac816b8a53190e4390d","unresolved":false,"context_lines":[{"line_number":21,"context_line":"    policy.DocumentedRuleDefault("},{"line_number":22,"context_line":"        name\u003dbase.IDENTITY % \u0027get_application_credential\u0027,"},{"line_number":23,"context_line":"        check_str\u003dbase.RULE_ADMIN_OR_OWNER,"},{"line_number":24,"context_line":"        scope_types\u003d[\u0027system\u0027, \u0027project\u0027],"},{"line_number":25,"context_line":"        description\u003d\u0027Show application credential details.\u0027,"},{"line_number":26,"context_line":"        operations\u003d[{\u0027path\u0027: resource_path,"},{"line_number":27,"context_line":"                     \u0027method\u0027: \u0027GET\u0027},"}],"source_content_type":"text/x-python","patch_set":33,"id":"7f96bb07_43e3d1d9","line":24,"range":{"start_line":24,"start_character":8,"end_line":24,"end_character":19},"in_reply_to":"7f96bb07_8d282a97","updated":"2018-01-17 21:32:00.000000000","message":"Well - a system administrator should be able to look up any credential, same as they could look up any user.\n\nI\u0027m not totally sure a project admin should be able to look these up. Would they be allowed to look up users in their project? But it needs to have a project scope because a user looking up their own credential needs to be scoped on a project.","commit_id":"d823c402758635f967aa1025e43e90c281221a61"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"0e122cee1a0ca7be36f96ecacc31f79026f2ec2e","unresolved":false,"context_lines":[{"line_number":30,"context_line":"    policy.DocumentedRuleDefault("},{"line_number":31,"context_line":"        name\u003dbase.IDENTITY % \u0027list_application_credentials\u0027,"},{"line_number":32,"context_line":"        check_str\u003dbase.RULE_ADMIN_OR_OWNER,"},{"line_number":33,"context_line":"        scope_types\u003d[\u0027system\u0027, \u0027project\u0027],"},{"line_number":34,"context_line":"        description\u003d\u0027List application credentials for a user.\u0027,"},{"line_number":35,"context_line":"        operations\u003d[{\u0027path\u0027: collection_path,"},{"line_number":36,"context_line":"                     \u0027method\u0027: \u0027GET\u0027},"}],"source_content_type":"text/x-python","patch_set":33,"id":"7f96bb07_ad108658","line":33,"range":{"start_line":33,"start_character":8,"end_line":33,"end_character":19},"updated":"2018-01-17 20:55:45.000000000","message":"The same comment here.","commit_id":"d823c402758635f967aa1025e43e90c281221a61"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"8d40f756ae63a51df041667e261f5c3b1c4807da","unresolved":false,"context_lines":[{"line_number":21,"context_line":"    policy.DocumentedRuleDefault("},{"line_number":22,"context_line":"        name\u003dbase.IDENTITY % \u0027get_application_credential\u0027,"},{"line_number":23,"context_line":"        check_str\u003dbase.RULE_ADMIN_OR_OWNER,"},{"line_number":24,"context_line":"        scope_types\u003d[\u0027system\u0027, \u0027project\u0027],"},{"line_number":25,"context_line":"        description\u003d\u0027Show application credential details.\u0027,"},{"line_number":26,"context_line":"        operations\u003d[{\u0027path\u0027: resource_path,"},{"line_number":27,"context_line":"                     \u0027method\u0027: \u0027GET\u0027},"}],"source_content_type":"text/x-python","patch_set":37,"id":"7f96bb07_6d58cc55","line":24,"updated":"2018-01-22 15:07:16.000000000","message":"I think this will need a FIXME like some of the other scope_types patches.\n\nA system administrator should be able to get any application credential. A user with a role on a project should only be able to get application credentials they\u0027ve created. What about project administrators? Should they have the ability to control application credentials for the project they own?\n\nIn that case, is it best to leave this commented out with a FIXME?","commit_id":"f29a5a8d12eb6e048d2966b31ec8635a6165cbd7"}],"keystone/tests/unit/test_v3_application_credential.py":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"0e122cee1a0ca7be36f96ecacc31f79026f2ec2e","unresolved":false,"context_lines":[{"line_number":24,"context_line":""},{"line_number":25,"context_line":"CONF \u003d keystone.conf.CONF"},{"line_number":26,"context_line":"PROVIDERS \u003d provider_api.ProviderAPIs"},{"line_number":27,"context_line":"MEMBER_PATH_FMT \u003d \u0027/users/%(user_id)s/application_credentials/%(app_cred_id)s\u0027"},{"line_number":28,"context_line":""},{"line_number":29,"context_line":""},{"line_number":30,"context_line":"class ApplicationCredentialTestCase(test_v3.RestfulTestCase):"}],"source_content_type":"text/x-python","patch_set":33,"id":"7f96bb07_1072f1ad","line":27,"range":{"start_line":27,"start_character":0,"end_line":27,"end_character":15},"updated":"2018-01-17 20:55:45.000000000","message":"Smart... this is a good idea. I always type this url out over and over when working with functional tests.","commit_id":"d823c402758635f967aa1025e43e90c281221a61"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"0e122cee1a0ca7be36f96ecacc31f79026f2ec2e","unresolved":false,"context_lines":[{"line_number":65,"context_line":"                         expected_status\u003dhttp_client.CREATED)"},{"line_number":66,"context_line":"        self.assertEqual(secret, resp.json[\u0027application_credential\u0027][\u0027secret\u0027])"},{"line_number":67,"context_line":""},{"line_number":68,"context_line":"    def test_create_application_credential_implicit_roles(self):"},{"line_number":69,"context_line":"        app_cred_body \u003d self._app_cred_body()"},{"line_number":70,"context_line":"        resp \u003d self.post(\u0027/users/%s/application_credentials\u0027 % self.user_id,"},{"line_number":71,"context_line":"                         body\u003dapp_cred_body,"}],"source_content_type":"text/x-python","patch_set":33,"id":"7f96bb07_90c36157","line":68,"range":{"start_line":68,"start_character":43,"end_line":68,"end_character":51},"updated":"2018-01-17 20:55:45.000000000","message":"By implicit here we actually mean the roles from the token are used when creating the application credential. This doesn\u0027t rely on the implied roles feature, does it?","commit_id":"d823c402758635f967aa1025e43e90c281221a61"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"0deb5492d27ee0b1c3785ac816b8a53190e4390d","unresolved":false,"context_lines":[{"line_number":65,"context_line":"                         expected_status\u003dhttp_client.CREATED)"},{"line_number":66,"context_line":"        self.assertEqual(secret, resp.json[\u0027application_credential\u0027][\u0027secret\u0027])"},{"line_number":67,"context_line":""},{"line_number":68,"context_line":"    def test_create_application_credential_implicit_roles(self):"},{"line_number":69,"context_line":"        app_cred_body \u003d self._app_cred_body()"},{"line_number":70,"context_line":"        resp \u003d self.post(\u0027/users/%s/application_credentials\u0027 % self.user_id,"},{"line_number":71,"context_line":"                         body\u003dapp_cred_body,"}],"source_content_type":"text/x-python","patch_set":33,"id":"7f96bb07_e3fe9d69","line":68,"range":{"start_line":68,"start_character":43,"end_line":68,"end_character":51},"in_reply_to":"7f96bb07_90c36157","updated":"2018-01-17 21:32:00.000000000","message":"Yeah that\u0027s what I meant, I originally had _implied_roles and realized that was overloaded, but you\u0027re right this isn\u0027t much clearer. Maybe _roles_from_token?","commit_id":"d823c402758635f967aa1025e43e90c281221a61"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"672faa4b01be4400cf470f3c2ec48f385c5e6b68","unresolved":false,"context_lines":[{"line_number":65,"context_line":"                         expected_status\u003dhttp_client.CREATED)"},{"line_number":66,"context_line":"        self.assertEqual(secret, resp.json[\u0027application_credential\u0027][\u0027secret\u0027])"},{"line_number":67,"context_line":""},{"line_number":68,"context_line":"    def test_create_application_credential_implicit_roles(self):"},{"line_number":69,"context_line":"        app_cred_body \u003d self._app_cred_body()"},{"line_number":70,"context_line":"        resp \u003d self.post(\u0027/users/%s/application_credentials\u0027 % self.user_id,"},{"line_number":71,"context_line":"                         body\u003dapp_cred_body,"}],"source_content_type":"text/x-python","patch_set":33,"id":"7f96bb07_a38bb5c0","line":68,"range":{"start_line":68,"start_character":43,"end_line":68,"end_character":51},"in_reply_to":"7f96bb07_e3fe9d69","updated":"2018-01-17 21:42:43.000000000","message":"++ that works for me. Thanks for clarifying!","commit_id":"d823c402758635f967aa1025e43e90c281221a61"}],"keystone/version/service.py":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"0e122cee1a0ca7be36f96ecacc31f79026f2ec2e","unresolved":false,"context_lines":[{"line_number":133,"context_line":"                       federation_routers,"},{"line_number":134,"context_line":"                       oauth1_routers,"},{"line_number":135,"context_line":"                       endpoint_policy_routers,"},{"line_number":136,"context_line":"                       app_cred_routers,"},{"line_number":137,"context_line":"                       # TODO(morganfainberg): Remove the simple_cert router"},{"line_number":138,"context_line":"                       # when PKI and PKIZ tokens are removed."},{"line_number":139,"context_line":"                       simple_cert_ext]"}],"source_content_type":"text/x-python","patch_set":33,"id":"7f96bb07_d086c9b9","line":136,"range":{"start_line":136,"start_character":23,"end_line":136,"end_character":39},"updated":"2018-01-17 20:55:45.000000000","message":"Based on dstanek\u0027s comment on line 122, should this be bumped up the stack? Surely this will be used more than the policy API?","commit_id":"d823c402758635f967aa1025e43e90c281221a61"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"672faa4b01be4400cf470f3c2ec48f385c5e6b68","unresolved":false,"context_lines":[{"line_number":133,"context_line":"                       federation_routers,"},{"line_number":134,"context_line":"                       oauth1_routers,"},{"line_number":135,"context_line":"                       endpoint_policy_routers,"},{"line_number":136,"context_line":"                       app_cred_routers,"},{"line_number":137,"context_line":"                       # TODO(morganfainberg): Remove the simple_cert router"},{"line_number":138,"context_line":"                       # when PKI and PKIZ tokens are removed."},{"line_number":139,"context_line":"                       simple_cert_ext]"}],"source_content_type":"text/x-python","patch_set":33,"id":"7f96bb07_439bd116","line":136,"range":{"start_line":136,"start_character":23,"end_line":136,"end_character":39},"in_reply_to":"7f96bb07_63f28d9c","updated":"2018-01-17 21:42:43.000000000","message":"Right, maybe this who list needs a bit of reordering..","commit_id":"d823c402758635f967aa1025e43e90c281221a61"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"0deb5492d27ee0b1c3785ac816b8a53190e4390d","unresolved":false,"context_lines":[{"line_number":133,"context_line":"                       federation_routers,"},{"line_number":134,"context_line":"                       oauth1_routers,"},{"line_number":135,"context_line":"                       endpoint_policy_routers,"},{"line_number":136,"context_line":"                       app_cred_routers,"},{"line_number":137,"context_line":"                       # TODO(morganfainberg): Remove the simple_cert router"},{"line_number":138,"context_line":"                       # when PKI and PKIZ tokens are removed."},{"line_number":139,"context_line":"                       simple_cert_ext]"}],"source_content_type":"text/x-python","patch_set":33,"id":"7f96bb07_63f28d9c","line":136,"range":{"start_line":136,"start_character":23,"end_line":136,"end_character":39},"in_reply_to":"7f96bb07_d086c9b9","updated":"2018-01-17 21:32:00.000000000","message":"Good call. But I\u0027m surprised resource_routers is below policy_routers?","commit_id":"d823c402758635f967aa1025e43e90c281221a61"}]}
