)]}'
{"doc/source/configuration.rst":[{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"9ce505bf13c6427c10eeebad527910d1bd91e9df","unresolved":false,"context_lines":[{"line_number":90,"context_line":""},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"Authentication Plug-in"},{"line_number":93,"context_line":"----------------------"},{"line_number":94,"context_line":"Keystone support authentication plug-ins. Authentication plug-in modules are"},{"line_number":95,"context_line":"specified in the ``[auth]`` section of the configuration file. However, an"},{"line_number":96,"context_line":"authentication plug-in may also have its own section in the configuration"}],"source_content_type":"text/x-rst","patch_set":6,"id":"AAAAM3%2F%2B6Xs%3D","line":93,"updated":"2013-02-14 18:09:34.000000000","message":"line break after section title\u0027s underline; maybe make Plugin plural","commit_id":"5daf44090947d04c3d330a1aed07cdbf3d57e762"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"9ce505bf13c6427c10eeebad527910d1bd91e9df","unresolved":false,"context_lines":[{"line_number":91,"context_line":""},{"line_number":92,"context_line":"Authentication Plug-in"},{"line_number":93,"context_line":"----------------------"},{"line_number":94,"context_line":"Keystone support authentication plug-ins. Authentication plug-in modules are"},{"line_number":95,"context_line":"specified in the ``[auth]`` section of the configuration file. However, an"},{"line_number":96,"context_line":"authentication plug-in may also have its own section in the configuration"},{"line_number":97,"context_line":"file. It is up to the plug-in to register their own configuration options."}],"source_content_type":"text/x-rst","patch_set":6,"id":"AAAAM3%2F%2B6Xg%3D","line":94,"updated":"2013-02-14 18:09:34.000000000","message":"I vote for plug-in/plug-ins -\u003e plugin/plugins","commit_id":"5daf44090947d04c3d330a1aed07cdbf3d57e762"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"9ce505bf13c6427c10eeebad527910d1bd91e9df","unresolved":false,"context_lines":[{"line_number":94,"context_line":"Keystone support authentication plug-ins. Authentication plug-in modules are"},{"line_number":95,"context_line":"specified in the ``[auth]`` section of the configuration file. However, an"},{"line_number":96,"context_line":"authentication plug-in may also have its own section in the configuration"},{"line_number":97,"context_line":"file. It is up to the plug-in to register their own configuration options."},{"line_number":98,"context_line":""},{"line_number":99,"context_line":"* ``methods`` - comma-delimited list of authentication plug-in names"},{"line_number":100,"context_line":"* ``\u003cplug-in name\u003e`` - specify the class which handles to authentication method, in the same manner as one would specify a backend driver."}],"source_content_type":"text/x-rst","patch_set":6,"id":"AAAAM3%2F%2B6XU%3D","line":97,"updated":"2013-02-14 18:09:34.000000000","message":"their -\u003e it\u0027s","commit_id":"5daf44090947d04c3d330a1aed07cdbf3d57e762"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"9ce505bf13c6427c10eeebad527910d1bd91e9df","unresolved":false,"context_lines":[{"line_number":101,"context_line":""},{"line_number":102,"context_line":"Keystone provides two authentication methods by default. ``password`` handles password authentication and ``token`` handles token authentication."},{"line_number":103,"context_line":""},{"line_number":104,"context_line":"How To Implement An Authentication-Plugin"},{"line_number":105,"context_line":"^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"},{"line_number":106,"context_line":""},{"line_number":107,"context_line":"All authentication plug-in must extends keystone.auth.core.AuthMethodHandler"}],"source_content_type":"text/x-rst","patch_set":6,"id":"AAAAM3%2F%2B6XE%3D","line":104,"updated":"2013-02-14 18:09:34.000000000","message":"To -\u003e to, An -\u003e an","commit_id":"5daf44090947d04c3d330a1aed07cdbf3d57e762"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"9ce505bf13c6427c10eeebad527910d1bd91e9df","unresolved":false,"context_lines":[{"line_number":104,"context_line":"How To Implement An Authentication-Plugin"},{"line_number":105,"context_line":"^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"},{"line_number":106,"context_line":""},{"line_number":107,"context_line":"All authentication plug-in must extends keystone.auth.core.AuthMethodHandler"},{"line_number":108,"context_line":"class and implements the authenticate() method. It is expecting the following"},{"line_number":109,"context_line":"parameters."},{"line_number":110,"context_line":""}],"source_content_type":"text/x-rst","patch_set":6,"id":"AAAAM3%2F%2B6W0%3D","line":107,"updated":"2013-02-14 18:09:34.000000000","message":"``backticks`` around the class path","commit_id":"5daf44090947d04c3d330a1aed07cdbf3d57e762"},{"author":{"_account_id":6460,"name":"Brad Topol","email":"btopol@us.ibm.com","username":"btopol"},"change_message_id":"e46de455d4be952ccf5a79dd60c19ebdf25dcad6","unresolved":false,"context_lines":[{"line_number":104,"context_line":"How To Implement An Authentication-Plugin"},{"line_number":105,"context_line":"^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"},{"line_number":106,"context_line":""},{"line_number":107,"context_line":"All authentication plug-in must extends keystone.auth.core.AuthMethodHandler"},{"line_number":108,"context_line":"class and implements the authenticate() method. It is expecting the following"},{"line_number":109,"context_line":"parameters."},{"line_number":110,"context_line":""}],"source_content_type":"text/x-rst","patch_set":6,"id":"AAAAM3%2F%2B6WY%3D","line":107,"updated":"2013-02-14 18:11:25.000000000","message":"typo plug-in should be plug-ins\nAlso it would be helpful to tell the user the recommended best practice of where they should put the plug-in code that they write.  Do we have a particular directory that we recommend the plugins be placed in?","commit_id":"5daf44090947d04c3d330a1aed07cdbf3d57e762"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"b7c38b85ca5aacc65165defbe79fbbb923325308","unresolved":false,"context_lines":[{"line_number":104,"context_line":"How To Implement An Authentication-Plugin"},{"line_number":105,"context_line":"^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"},{"line_number":106,"context_line":""},{"line_number":107,"context_line":"All authentication plug-in must extends keystone.auth.core.AuthMethodHandler"},{"line_number":108,"context_line":"class and implements the authenticate() method. It is expecting the following"},{"line_number":109,"context_line":"parameters."},{"line_number":110,"context_line":""}],"source_content_type":"text/x-rst","patch_set":6,"id":"AAAAM3%2F%2B6S0%3D","line":107,"in_reply_to":"AAAAM3%2F%2B6WY%3D","updated":"2013-02-14 18:21:34.000000000","message":"that\u0027s the cool part -- they don\u0027t have to be part of keystone, they just need to be importable by package/class name. So if I wanted to write my own plugin that allowed anonymous access to anyone, i just have to give keystone the class path:\n\n  [auth]\n  methods \u003d anonymous\n  anonymous \u003d myproject.auth.plugins.AnonymousAuth","commit_id":"5daf44090947d04c3d330a1aed07cdbf3d57e762"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"9ce505bf13c6427c10eeebad527910d1bd91e9df","unresolved":false,"context_lines":[{"line_number":105,"context_line":"^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"},{"line_number":106,"context_line":""},{"line_number":107,"context_line":"All authentication plug-in must extends keystone.auth.core.AuthMethodHandler"},{"line_number":108,"context_line":"class and implements the authenticate() method. It is expecting the following"},{"line_number":109,"context_line":"parameters."},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"* ``context`` - Keystone context"}],"source_content_type":"text/x-rst","patch_set":6,"id":"AAAAM3%2F%2B6Wo%3D","line":108,"updated":"2013-02-14 18:09:34.000000000","message":"``backticks`` on method name","commit_id":"5daf44090947d04c3d330a1aed07cdbf3d57e762"},{"author":{"_account_id":6460,"name":"Brad Topol","email":"btopol@us.ibm.com","username":"btopol"},"change_message_id":"e46de455d4be952ccf5a79dd60c19ebdf25dcad6","unresolved":false,"context_lines":[{"line_number":105,"context_line":"^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"},{"line_number":106,"context_line":""},{"line_number":107,"context_line":"All authentication plug-in must extends keystone.auth.core.AuthMethodHandler"},{"line_number":108,"context_line":"class and implements the authenticate() method. It is expecting the following"},{"line_number":109,"context_line":"parameters."},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"* ``context`` - Keystone context"}],"source_content_type":"text/x-rst","patch_set":6,"id":"AAAAM3%2F%2B6WM%3D","line":108,"updated":"2013-02-14 18:11:25.000000000","message":"typo: implements should be implement","commit_id":"5daf44090947d04c3d330a1aed07cdbf3d57e762"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"9ce505bf13c6427c10eeebad527910d1bd91e9df","unresolved":false,"context_lines":[{"line_number":108,"context_line":"class and implements the authenticate() method. It is expecting the following"},{"line_number":109,"context_line":"parameters."},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"* ``context`` - Keystone context"},{"line_number":112,"context_line":"* ``auth_info`` - AuthInfo object which encapsulates the ``authenticate`` data."},{"line_number":113,"context_line":"* ``auth_context`` - user authentication context, a dictionary shared by all plug-ins. It contains an ``method_names`` and ``extras`` by default. ``method_names`` is a list and ``extras`` is a dictionary."},{"line_number":114,"context_line":""}],"source_content_type":"text/x-rst","patch_set":6,"id":"AAAAM3%2F%2B6Wc%3D","line":111,"updated":"2013-02-14 18:09:34.000000000","message":"maybe be slightly more specific here -- Keystone\u0027s request context?","commit_id":"5daf44090947d04c3d330a1aed07cdbf3d57e762"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"9ce505bf13c6427c10eeebad527910d1bd91e9df","unresolved":false,"context_lines":[{"line_number":109,"context_line":"parameters."},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"* ``context`` - Keystone context"},{"line_number":112,"context_line":"* ``auth_info`` - AuthInfo object which encapsulates the ``authenticate`` data."},{"line_number":113,"context_line":"* ``auth_context`` - user authentication context, a dictionary shared by all plug-ins. It contains an ``method_names`` and ``extras`` by default. ``method_names`` is a list and ``extras`` is a dictionary."},{"line_number":114,"context_line":""},{"line_number":115,"context_line":"If success, authenticate() must provide a valid ``user_id`` in ``auth_context``."}],"source_content_type":"text/x-rst","patch_set":6,"id":"AAAAM3%2F%2B6Wk%3D","line":112,"updated":"2013-02-14 18:09:34.000000000","message":"``backticks`` on class name","commit_id":"5daf44090947d04c3d330a1aed07cdbf3d57e762"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"9ce505bf13c6427c10eeebad527910d1bd91e9df","unresolved":false,"context_lines":[{"line_number":122,"context_line":""},{"line_number":123,"context_line":"The authenticate() method must return None on successful authentication. If"},{"line_number":124,"context_line":"authentication require multiple steps, the authenticate() method must return"},{"line_number":125,"context_line":"the payload for the next authentication step."},{"line_number":126,"context_line":""},{"line_number":127,"context_line":"If authentication is unsuccessful, the authenticate() method must raise an"},{"line_number":128,"context_line":"Unauthorized exception."}],"source_content_type":"text/x-rst","patch_set":6,"id":"AAAAM3%2F%2B6WU%3D","line":125,"updated":"2013-02-14 18:09:34.000000000","message":"``return None``\n\nalso add:\n\n   (doing so implicitly is sufficient)\n\nbecause all methods in python return None automatically unless you specify otherwise or raise an exception","commit_id":"5daf44090947d04c3d330a1aed07cdbf3d57e762"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"9ce505bf13c6427c10eeebad527910d1bd91e9df","unresolved":false,"context_lines":[{"line_number":125,"context_line":"the payload for the next authentication step."},{"line_number":126,"context_line":""},{"line_number":127,"context_line":"If authentication is unsuccessful, the authenticate() method must raise an"},{"line_number":128,"context_line":"Unauthorized exception."},{"line_number":129,"context_line":""},{"line_number":130,"context_line":"Certificates for PKI"},{"line_number":131,"context_line":"--------------------"}],"source_content_type":"text/x-rst","patch_set":6,"id":"AAAAM3%2F%2B6WQ%3D","line":128,"updated":"2013-02-14 18:09:34.000000000","message":"backticks on method name, raise keyword, and prefer being specific on the exception, e.g. ``keystone.exceptions.Unauthorized``","commit_id":"5daf44090947d04c3d330a1aed07cdbf3d57e762"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"42a46fa6494857e44dae8f3521644fdb8db4125c","unresolved":false,"context_lines":[{"line_number":92,"context_line":"Authentication Plugins"},{"line_number":93,"context_line":"----------------------"},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"Keystone support authentication plugins and they are specified"},{"line_number":96,"context_line":"in the ``[auth]`` section of the configuration file. However, an"},{"line_number":97,"context_line":"authentication plugin may also have its own section in the configuration"},{"line_number":98,"context_line":"file. It is up to the plugin to register its own configuration options."}],"source_content_type":"text/x-rst","patch_set":7,"id":"AAAAM3%2F%2B4pk%3D","line":95,"updated":"2013-02-15 17:49:31.000000000","message":"\"support\" -\u003e \"supports\"","commit_id":"1daa6bd277f91590083436bf3a729f3d1c3dc067"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"42a46fa6494857e44dae8f3521644fdb8db4125c","unresolved":false,"context_lines":[{"line_number":105,"context_line":"How to Implement an Authentication Plugin"},{"line_number":106,"context_line":"^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"},{"line_number":107,"context_line":""},{"line_number":108,"context_line":"All authentication plugins must extend ``keystone.auth.core.AuthMethodHandler``"},{"line_number":109,"context_line":"class and implement the ``authenticate()`` method. It is expecting the"},{"line_number":110,"context_line":"following parameters."},{"line_number":111,"context_line":""}],"source_content_type":"text/x-rst","patch_set":7,"id":"AAAAM3%2F%2B4o0%3D","line":108,"updated":"2013-02-15 17:49:31.000000000","message":"\"extend\" -\u003e \"extend the\"","commit_id":"1daa6bd277f91590083436bf3a729f3d1c3dc067"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"42a46fa6494857e44dae8f3521644fdb8db4125c","unresolved":false,"context_lines":[{"line_number":106,"context_line":"^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"},{"line_number":107,"context_line":""},{"line_number":108,"context_line":"All authentication plugins must extend ``keystone.auth.core.AuthMethodHandler``"},{"line_number":109,"context_line":"class and implement the ``authenticate()`` method. It is expecting the"},{"line_number":110,"context_line":"following parameters."},{"line_number":111,"context_line":""},{"line_number":112,"context_line":"* ``context`` - Keystone\u0027s request context"}],"source_content_type":"text/x-rst","patch_set":7,"id":"AAAAM3%2F%2B4o8%3D","line":109,"updated":"2013-02-15 17:49:31.000000000","message":"\"It is expecting\" -\u003e \"The ``authenticate()`` method expects\"","commit_id":"1daa6bd277f91590083436bf3a729f3d1c3dc067"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"42a46fa6494857e44dae8f3521644fdb8db4125c","unresolved":false,"context_lines":[{"line_number":115,"context_line":"* ``auth_context`` - user authentication context, a dictionary shared by all plugins. It contains ``method_names`` and ``extras`` by default. ``method_names`` is a list and ``extras`` is a dictionary."},{"line_number":116,"context_line":""},{"line_number":117,"context_line":"If successful, ``authenticate()`` must provide a valid ``user_id`` in"},{"line_number":118,"context_line":"``auth_context``. ``method_name`` is used to convey any additional"},{"line_number":119,"context_line":"authentication methods in case authentication is for re-scoping. For example,"},{"line_number":120,"context_line":"if the authentication is for re-scoping, a plugin must append the previous"},{"line_number":121,"context_line":"method names into ``method_names``. Also, plugin may add any additional"}],"source_content_type":"text/x-rst","patch_set":7,"id":"AAAAM3%2F%2B4nA%3D","line":118,"updated":"2013-02-15 17:49:31.000000000","message":"The next paragraph says that if authenticate() is successful, the method must return None. Suggest you combine both the requirements for successful authentication in one place. For example, say\n\n If successful, ``authenticate()`` must\n provide a valid ``user_id`` in ``auth_context`` and\n return ``None``.","commit_id":"1daa6bd277f91590083436bf3a729f3d1c3dc067"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"868bc4dd0e6a2f4f936c5c785c4b16b7774112c6","unresolved":false,"context_lines":[{"line_number":115,"context_line":"* ``auth_context`` - user authentication context, a dictionary shared by all plugins. It contains ``method_names`` and ``extras`` by default. ``method_names`` is a list and ``extras`` is a dictionary."},{"line_number":116,"context_line":""},{"line_number":117,"context_line":"If successful, ``authenticate()`` must provide a valid ``user_id`` in"},{"line_number":118,"context_line":"``auth_context``. ``method_name`` is used to convey any additional"},{"line_number":119,"context_line":"authentication methods in case authentication is for re-scoping. For example,"},{"line_number":120,"context_line":"if the authentication is for re-scoping, a plugin must append the previous"},{"line_number":121,"context_line":"method names into ``method_names``. Also, plugin may add any additional"}],"source_content_type":"text/x-rst","patch_set":7,"id":"AAAAM3%2F%2B4N8%3D","line":118,"in_reply_to":"AAAAM3%2F%2B4nA%3D","updated":"2013-02-15 18:38:23.000000000","message":"+1","commit_id":"1daa6bd277f91590083436bf3a729f3d1c3dc067"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"42a46fa6494857e44dae8f3521644fdb8db4125c","unresolved":false,"context_lines":[{"line_number":118,"context_line":"``auth_context``. ``method_name`` is used to convey any additional"},{"line_number":119,"context_line":"authentication methods in case authentication is for re-scoping. For example,"},{"line_number":120,"context_line":"if the authentication is for re-scoping, a plugin must append the previous"},{"line_number":121,"context_line":"method names into ``method_names``. Also, plugin may add any additional"},{"line_number":122,"context_line":"information into ``extras``. Anything in ``extras`` will be conveyed in the"},{"line_number":123,"context_line":"token\u0027s ``extras`` field."},{"line_number":124,"context_line":""}],"source_content_type":"text/x-rst","patch_set":7,"id":"AAAAM3%2F%2B4oE%3D","line":121,"updated":"2013-02-15 17:49:31.000000000","message":"\"plugin\" -\u003e \"a plugin\"","commit_id":"1daa6bd277f91590083436bf3a729f3d1c3dc067"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"42a46fa6494857e44dae8f3521644fdb8db4125c","unresolved":false,"context_lines":[{"line_number":122,"context_line":"information into ``extras``. Anything in ``extras`` will be conveyed in the"},{"line_number":123,"context_line":"token\u0027s ``extras`` field."},{"line_number":124,"context_line":""},{"line_number":125,"context_line":"The ``authenticate()`` method must ``return None`` (doing so implicitly is"},{"line_number":126,"context_line":"sufficient) on successful authentication. If authentication require"},{"line_number":127,"context_line":"multiple steps, the ``authenticate()`` method must return the payload in the"},{"line_number":128,"context_line":"form of a dictionary for the next authentication step."}],"source_content_type":"text/x-rst","patch_set":7,"id":"AAAAM3%2F%2B4nw%3D","line":125,"updated":"2013-02-15 17:49:31.000000000","message":"\"``return None``\" -\u003e \"return ``None``\"","commit_id":"1daa6bd277f91590083436bf3a729f3d1c3dc067"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"868bc4dd0e6a2f4f936c5c785c4b16b7774112c6","unresolved":false,"context_lines":[{"line_number":122,"context_line":"information into ``extras``. Anything in ``extras`` will be conveyed in the"},{"line_number":123,"context_line":"token\u0027s ``extras`` field."},{"line_number":124,"context_line":""},{"line_number":125,"context_line":"The ``authenticate()`` method must ``return None`` (doing so implicitly is"},{"line_number":126,"context_line":"sufficient) on successful authentication. If authentication require"},{"line_number":127,"context_line":"multiple steps, the ``authenticate()`` method must return the payload in the"},{"line_number":128,"context_line":"form of a dictionary for the next authentication step."}],"source_content_type":"text/x-rst","patch_set":7,"id":"AAAAM3%2F%2B4OI%3D","line":125,"in_reply_to":"AAAAM3%2F%2B4nw%3D","updated":"2013-02-15 18:38:23.000000000","message":"i prefer the original","commit_id":"1daa6bd277f91590083436bf3a729f3d1c3dc067"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"42a46fa6494857e44dae8f3521644fdb8db4125c","unresolved":false,"context_lines":[{"line_number":123,"context_line":"token\u0027s ``extras`` field."},{"line_number":124,"context_line":""},{"line_number":125,"context_line":"The ``authenticate()`` method must ``return None`` (doing so implicitly is"},{"line_number":126,"context_line":"sufficient) on successful authentication. If authentication require"},{"line_number":127,"context_line":"multiple steps, the ``authenticate()`` method must return the payload in the"},{"line_number":128,"context_line":"form of a dictionary for the next authentication step."},{"line_number":129,"context_line":""}],"source_content_type":"text/x-rst","patch_set":7,"id":"AAAAM3%2F%2B4n0%3D","line":126,"updated":"2013-02-15 17:49:31.000000000","message":"\"require\" -\u003e \"requires\"","commit_id":"1daa6bd277f91590083436bf3a729f3d1c3dc067"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"42a46fa6494857e44dae8f3521644fdb8db4125c","unresolved":false,"context_lines":[{"line_number":127,"context_line":"multiple steps, the ``authenticate()`` method must return the payload in the"},{"line_number":128,"context_line":"form of a dictionary for the next authentication step."},{"line_number":129,"context_line":""},{"line_number":130,"context_line":"If authentication is unsuccessful, the ``authenticate()`` method must raise an"},{"line_number":131,"context_line":"``keystone.exception.Unauthorized`` exception."},{"line_number":132,"context_line":""},{"line_number":133,"context_line":"Simply add the new plugin name to the ``methods`` list along with your plugin"}],"source_content_type":"text/x-rst","patch_set":7,"id":"AAAAM3%2F%2B4ns%3D","line":130,"updated":"2013-02-15 17:49:31.000000000","message":"\"an\" -\u003e \"a\"","commit_id":"1daa6bd277f91590083436bf3a729f3d1c3dc067"},{"author":{"_account_id":6460,"name":"Brad Topol","email":"btopol@us.ibm.com","username":"btopol"},"change_message_id":"57caf0f1f5b6e96846eb0b9dbe716f7a2d14df22","unresolved":false,"context_lines":[{"line_number":137,"context_line":"If the plugin require addition configurations, it may register its own section"},{"line_number":138,"context_line":"in the configuration file."},{"line_number":139,"context_line":""},{"line_number":140,"context_line":"Plugins are invoked in the order in which they are specified in the ``methods``"},{"line_number":141,"context_line":"attribute of the ``authentication`` request body."},{"line_number":142,"context_line":""},{"line_number":143,"context_line":"Certificates for PKI"}],"source_content_type":"text/x-rst","patch_set":16,"id":"AAAAM3%2F%2BwF0%3D","line":140,"updated":"2013-02-19 23:32:28.000000000","message":"OK, so all three run but what are the semantics?  Does only one of them have to succeed?  Do they each have if statements (like the Token plugin appears to do) to they are able to self-select themselves out of trying to authenticate if they don\u0027t have the proper inputs?  Clarifying this would really be helpful","commit_id":"8cba920518ddd87ec99ce464f666e59c1ecd3abf"},{"author":{"_account_id":6460,"name":"Brad Topol","email":"btopol@us.ibm.com","username":"btopol"},"change_message_id":"7d53e5f5b1763ec48c77f3e2a6285816be74a5f8","unresolved":false,"context_lines":[{"line_number":138,"context_line":""},{"line_number":139,"context_line":"Plugins are invoked in the order in which they are specified in the ``methods``"},{"line_number":140,"context_line":"attribute of the ``authentication`` request body. If multiple plugins are"},{"line_number":141,"context_line":"invoked, all plugins must be succeeded in order to for the entire"},{"line_number":142,"context_line":"authentication to be successful. Furthermore, all the plugins invoked must"},{"line_number":143,"context_line":"agreed on the ``user_id`` in the ``auth_context``."},{"line_number":144,"context_line":""}],"source_content_type":"text/x-rst","patch_set":17,"id":"AAAAM3%2F%2Bu28%3D","line":141,"updated":"2013-02-20 14:00:27.000000000","message":"typo  \"must be succeeded\"  should be \"must suceed\"","commit_id":"383a77cbdf12c451f1032ecf1f5e8a35b5354847"},{"author":{"_account_id":6460,"name":"Brad Topol","email":"btopol@us.ibm.com","username":"btopol"},"change_message_id":"7d53e5f5b1763ec48c77f3e2a6285816be74a5f8","unresolved":false,"context_lines":[{"line_number":140,"context_line":"attribute of the ``authentication`` request body. If multiple plugins are"},{"line_number":141,"context_line":"invoked, all plugins must be succeeded in order to for the entire"},{"line_number":142,"context_line":"authentication to be successful. Furthermore, all the plugins invoked must"},{"line_number":143,"context_line":"agreed on the ``user_id`` in the ``auth_context``."},{"line_number":144,"context_line":""},{"line_number":145,"context_line":"Certificates for PKI"},{"line_number":146,"context_line":"--------------------"}],"source_content_type":"text/x-rst","patch_set":17,"id":"AAAAM3%2F%2Bu20%3D","line":143,"updated":"2013-02-20 14:00:27.000000000","message":"typo agreed should be agree","commit_id":"383a77cbdf12c451f1032ecf1f5e8a35b5354847"}],"etc/keystone.conf.sample":[{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"0cc06797a3047b1f3e48cbeb7b3faf0c09fd22af","unresolved":false,"context_lines":[{"line_number":184,"context_line":"[auth]"},{"line_number":185,"context_line":"methods \u003d password,token"},{"line_number":186,"context_line":"password \u003d keystone.auth.methods.password.Password"},{"line_number":187,"context_line":"token \u003d keystone.auth.methods.token.Token"},{"line_number":188,"context_line":""},{"line_number":189,"context_line":"[filter:debug]"},{"line_number":190,"context_line":"paste.filter_factory \u003d keystone.common.wsgi:Debug.factory"}],"source_content_type":"application/octet-stream","patch_set":3,"id":"AAAAM3%2F%2B%2B9o%3D","line":187,"updated":"2013-02-12 15:42:20.000000000","message":"that works -- each method can still look for its own config if necessary","commit_id":"026f19ee81eeb09f1aba9c287189495627e833aa"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"2ad0614b662b5a193961abd6437f32848fb0dd0c","unresolved":false,"context_lines":[{"line_number":184,"context_line":"[auth]"},{"line_number":185,"context_line":"methods \u003d password,token"},{"line_number":186,"context_line":"password \u003d keystone.auth.methods.password.Password"},{"line_number":187,"context_line":"token \u003d keystone.auth.methods.token.Token"},{"line_number":188,"context_line":""},{"line_number":189,"context_line":"[filter:debug]"},{"line_number":190,"context_line":"paste.filter_factory \u003d keystone.common.wsgi:Debug.factory"}],"source_content_type":"application/octet-stream","patch_set":3,"id":"AAAAM3%2F%2B%2B4M%3D","line":187,"in_reply_to":"AAAAM3%2F%2B%2B9o%3D","updated":"2013-02-12 15:54:16.000000000","message":"That\u0027s correct. It\u0027s up to the plugin itself.","commit_id":"026f19ee81eeb09f1aba9c287189495627e833aa"}],"keystone/auth/__init__.py":[{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"0cc06797a3047b1f3e48cbeb7b3faf0c09fd22af","unresolved":false,"context_lines":[{"line_number":16,"context_line":""},{"line_number":17,"context_line":"from keystone.auth import controllers"},{"line_number":18,"context_line":"from keystone.auth import routers"},{"line_number":19,"context_line":"from keystone.auth.core import *"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAAM3%2F%2B%2B9U%3D","line":19,"updated":"2013-02-12 15:42:20.000000000","message":"i want to make an exception for this import order (import all should come either last or first IMO), but the import order police will come and change this without an exception in HACKING","commit_id":"026f19ee81eeb09f1aba9c287189495627e833aa"},{"author":{"_account_id":6,"name":"Joe Heck","email":"heckj@mac.com","username":"heckj"},"change_message_id":"5b2c6c596329f210a9bc0abf3661cde2f73a7c58","unresolved":false,"context_lines":[{"line_number":15,"context_line":"# under the License."},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"from keystone.auth import controllers"},{"line_number":18,"context_line":"from keystone.auth.core import *"},{"line_number":19,"context_line":"from keystone.auth import routers"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAM3%2F%2B3XQ%3D","line":18,"updated":"2013-02-16 01:56:22.000000000","message":"can we make this a specific set of imports please?","commit_id":"25e13fffbfc512595c1ca19fd378df7d21745056"}],"keystone/auth/controllers.py":[{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"bbc81e0d674e56c142aceb4c518a1a51eea27aba","unresolved":false,"context_lines":[{"line_number":217,"context_line":"                exception.AuthMethodNotSupported,"},{"line_number":218,"context_line":"                exception.AdditionalAuthRequired) as e:"},{"line_number":219,"context_line":"            raise e"},{"line_number":220,"context_line":"        except Exception as ae:"},{"line_number":221,"context_line":"            raise exception.Unauthorized(ae)"},{"line_number":222,"context_line":""},{"line_number":223,"context_line":"    def _build_remote_user_auth_context(self, context, auth_info,"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2FDzU%3D","line":220,"updated":"2013-02-08 17:42:43.000000000","message":"something totally unnexpected shouldn\u0027t be caught here -- let it raise a proper 500 -- unless you\u0027re trying to suppress the security details? worth a thought","commit_id":"f03a5dc460399d89064cce9ecf521fad55e26a3a"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"03e156601c97b1b200e8a6e877079ef97fcb25a8","unresolved":false,"context_lines":[{"line_number":217,"context_line":"                exception.AuthMethodNotSupported,"},{"line_number":218,"context_line":"                exception.AdditionalAuthRequired) as e:"},{"line_number":219,"context_line":"            raise e"},{"line_number":220,"context_line":"        except Exception as ae:"},{"line_number":221,"context_line":"            raise exception.Unauthorized(ae)"},{"line_number":222,"context_line":""},{"line_number":223,"context_line":"    def _build_remote_user_auth_context(self, context, auth_info,"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2FDj0%3D","line":220,"in_reply_to":"AAAAM3%2F%2FDzU%3D","updated":"2013-02-08 19:27:44.000000000","message":"Yeah, conventional wisdom calls for not (accidentally) exposing the internal details of a security system to the clients via error messages.","commit_id":"f03a5dc460399d89064cce9ecf521fad55e26a3a"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"0cc06797a3047b1f3e48cbeb7b3faf0c09fd22af","unresolved":false,"context_lines":[{"line_number":23,"context_line":"from keystone.openstack.common import importutils"},{"line_number":24,"context_line":"from keystone.auth import token_factory"},{"line_number":25,"context_line":"from keystone.token import controllers as token_controllers"},{"line_number":26,"context_line":"from keystone.token import core"},{"line_number":27,"context_line":""},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"LOG \u003d logging.getLogger(__name__)"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAAM3%2F%2B%2B9M%3D","line":26,"updated":"2013-02-12 15:42:20.000000000","message":"these definitely need to be cleaned up\n\n- import order\n- do `from keystone import token`\n- remove the reference to `core`\n- remove the import for token_controllers in favor of referencing token.controllers below","commit_id":"026f19ee81eeb09f1aba9c287189495627e833aa"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"b24090c25b4b8f300b29ee344433cee31bd56e09","unresolved":false,"context_lines":[{"line_number":116,"context_line":"            try:"},{"line_number":117,"context_line":"                if project_name:"},{"line_number":118,"context_line":"                    project_ref \u003d self.identity_api.get_project_by_name("},{"line_number":119,"context_line":"                        context\u003dself.context, tenant_name\u003dproject_name)"},{"line_number":120,"context_line":"                else:"},{"line_number":121,"context_line":"                    project_ref \u003d self.identity_api.get_project("},{"line_number":122,"context_line":"                        context\u003dself.context, project_id\u003dproject_id)"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAAM3%2F%2B%2Bug%3D","line":119,"updated":"2013-02-12 17:30:52.000000000","message":"fyi, in the backend prep change (https://review.openstack.org/#/c/19820/) this function now takes a domain_id as an additional parameter","commit_id":"026f19ee81eeb09f1aba9c287189495627e833aa"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"50d80ea0b66b6ec76ffb3bc4ade48c3a393b4e4e","unresolved":false,"context_lines":[{"line_number":248,"context_line":"            # scope is specified"},{"line_number":249,"context_line":"            return"},{"line_number":250,"context_line":""},{"line_number":251,"context_line":"        # fill in default_project_id if it is available"},{"line_number":252,"context_line":"        try:"},{"line_number":253,"context_line":"            user_ref \u003d self.identity_api.get_user("},{"line_number":254,"context_line":"                context\u003dcontext, user_id\u003dauth_context[\u0027user_id\u0027])"}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAM3%2F%2B9aM%3D","line":251,"updated":"2013-02-13 06:38:13.000000000","message":"+2 for doing this here rather than stuffing it in as a final check in the middleware (as we do currently).  Should remember to not to that check in the middleware for v3 tokens (although it would be benign since it only does it if there is no project in there yet)","commit_id":"80fc831cc27513c18d63b0a5ef48305289477bd5"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"b3d7977d396ad1368cd80dc2cb4eccca5b5468d6","unresolved":false,"context_lines":[{"line_number":248,"context_line":"            # scope is specified"},{"line_number":249,"context_line":"            return"},{"line_number":250,"context_line":""},{"line_number":251,"context_line":"        # fill in default_project_id if it is available"},{"line_number":252,"context_line":"        try:"},{"line_number":253,"context_line":"            user_ref \u003d self.identity_api.get_user("},{"line_number":254,"context_line":"                context\u003dcontext, user_id\u003dauth_context[\u0027user_id\u0027])"}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAM3%2F%2B84M%3D","line":251,"in_reply_to":"AAAAM3%2F%2B9aM%3D","updated":"2013-02-13 14:20:42.000000000","message":"This is how we did it in diablo; I prefer this approach as well.","commit_id":"80fc831cc27513c18d63b0a5ef48305289477bd5"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"42a46fa6494857e44dae8f3521644fdb8db4125c","unresolved":false,"context_lines":[{"line_number":33,"context_line":"CONF \u003d config.CONF"},{"line_number":34,"context_line":""},{"line_number":35,"context_line":"# registry of authentication methods"},{"line_number":36,"context_line":"AUTH_METHODS \u003d {}"},{"line_number":37,"context_line":""},{"line_number":38,"context_line":""},{"line_number":39,"context_line":"# register method drivers"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAM3%2F%2B4kM%3D","line":36,"updated":"2013-02-15 17:49:31.000000000","message":"suggest change to a class AuthMethods with .load(method_name), .get(method_name).","commit_id":"1daa6bd277f91590083436bf3a729f3d1c3dc067"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"42a46fa6494857e44dae8f3521644fdb8db4125c","unresolved":false,"context_lines":[{"line_number":50,"context_line":"        driver \u003d CONF.auth.get(method_name)"},{"line_number":51,"context_line":"        return importutils.import_object(driver)"},{"line_number":52,"context_line":"    else:"},{"line_number":53,"context_line":"        raise exception.AuthMethodNotSupported()"},{"line_number":54,"context_line":""},{"line_number":55,"context_line":""},{"line_number":56,"context_line":"def get_auth_method(method_name):"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAM3%2F%2B4kw%3D","line":53,"updated":"2013-02-15 17:49:31.000000000","message":"suggest change this method to check for error at beginning\n\n if method_name not in CONF.auth.methods:\n   raise exception.AuthMethodNotSupported()\n\nso it\u0027s more obvious to us reviewers.","commit_id":"1daa6bd277f91590083436bf3a729f3d1c3dc067"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"42a46fa6494857e44dae8f3521644fdb8db4125c","unresolved":false,"context_lines":[{"line_number":67,"context_line":"        self.identity_api \u003d identity.Manager()"},{"line_number":68,"context_line":"        self.context \u003d context"},{"line_number":69,"context_line":"        self.auth \u003d auth"},{"line_number":70,"context_line":"        # scope data is (domain_id, project_id)"},{"line_number":71,"context_line":"        # project scope: (None, project_id)"},{"line_number":72,"context_line":"        # domain scope: (domain_id, None)"},{"line_number":73,"context_line":"        # unscoped: (None, None)"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAM3%2F%2B4jg%3D","line":70,"updated":"2013-02-15 17:49:31.000000000","message":"\"scope data\" -\u003e \"self._scope_data\", and move after the variable.","commit_id":"1daa6bd277f91590083436bf3a729f3d1c3dc067"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"42a46fa6494857e44dae8f3521644fdb8db4125c","unresolved":false,"context_lines":[{"line_number":71,"context_line":"        # project scope: (None, project_id)"},{"line_number":72,"context_line":"        # domain scope: (domain_id, None)"},{"line_number":73,"context_line":"        # unscoped: (None, None)"},{"line_number":74,"context_line":"        self._scope_data \u003d (None, None)"},{"line_number":75,"context_line":"        self._validate_and_normalize_auth_data()"},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"    def _assert_project_is_enabled(self, project_ref):"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAM3%2F%2B4d0%3D","line":74,"updated":"2013-02-15 17:49:31.000000000","message":"suggest change to a dict() with \u0027project_id\u0027 or \u0027domain_id\u0027 member.","commit_id":"1daa6bd277f91590083436bf3a729f3d1c3dc067"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"19a316154a1dec9a0790c4af8b2f84dd52fe0c0f","unresolved":false,"context_lines":[{"line_number":71,"context_line":"        # project scope: (None, project_id)"},{"line_number":72,"context_line":"        # domain scope: (domain_id, None)"},{"line_number":73,"context_line":"        # unscoped: (None, None)"},{"line_number":74,"context_line":"        self._scope_data \u003d (None, None)"},{"line_number":75,"context_line":"        self._validate_and_normalize_auth_data()"},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"    def _assert_project_is_enabled(self, project_ref):"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAM3%2F%2B3xE%3D","line":74,"in_reply_to":"AAAAM3%2F%2B4B8%3D","updated":"2013-02-15 21:51:54.000000000","message":"if you ever get the value out of self._scoped_data, to get the domain_id is _scoped_data[0] and project_id it\u0027s _scoped_data[1]. These are pretty much impossible to verify without looking back here for the documentation. If you use a dict, then getting the domain_id is _scoped_data[\u0027domain_id\u0027] and for project_id it\u0027s _scoped_data[\u0027project_id\u0027]. In the latter case, it\u0027s obviously correct. (although the key string could be typed wrong... this is python so you\u0027re pretty much stuck with a dynamic lookup at some point).","commit_id":"1daa6bd277f91590083436bf3a729f3d1c3dc067"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"b7153890402c9ef72b81e981115d1de11a9474df","unresolved":false,"context_lines":[{"line_number":71,"context_line":"        # project scope: (None, project_id)"},{"line_number":72,"context_line":"        # domain scope: (domain_id, None)"},{"line_number":73,"context_line":"        # unscoped: (None, None)"},{"line_number":74,"context_line":"        self._scope_data \u003d (None, None)"},{"line_number":75,"context_line":"        self._validate_and_normalize_auth_data()"},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"    def _assert_project_is_enabled(self, project_ref):"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAM3%2F%2B4B8%3D","line":74,"in_reply_to":"AAAAM3%2F%2B4d0%3D","updated":"2013-02-15 19:55:42.000000000","message":"What\u0027s the reason for putting them into a dict since we only care about either domain_id or project_id?","commit_id":"1daa6bd277f91590083436bf3a729f3d1c3dc067"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"42a46fa6494857e44dae8f3521644fdb8db4125c","unresolved":false,"context_lines":[{"line_number":75,"context_line":"        self._validate_and_normalize_auth_data()"},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"    def _assert_project_is_enabled(self, project_ref):"},{"line_number":78,"context_line":"        # making sure the project is enabled"},{"line_number":79,"context_line":"        if not project_ref.get(\u0027enabled\u0027, True):"},{"line_number":80,"context_line":"            msg \u003d _(\u0027Project is disabled: %s\u0027) % project_ref[\u0027id\u0027]"},{"line_number":81,"context_line":"            LOG.warning(msg)"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAM3%2F%2B4jc%3D","line":78,"updated":"2013-02-15 17:49:31.000000000","message":"\"making sure\" -\u003e \"ensure\"","commit_id":"1daa6bd277f91590083436bf3a729f3d1c3dc067"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"42a46fa6494857e44dae8f3521644fdb8db4125c","unresolved":false,"context_lines":[{"line_number":78,"context_line":"        # making sure the project is enabled"},{"line_number":79,"context_line":"        if not project_ref.get(\u0027enabled\u0027, True):"},{"line_number":80,"context_line":"            msg \u003d _(\u0027Project is disabled: %s\u0027) % project_ref[\u0027id\u0027]"},{"line_number":81,"context_line":"            LOG.warning(msg)"},{"line_number":82,"context_line":"            raise exception.Unauthorized(msg)"},{"line_number":83,"context_line":""},{"line_number":84,"context_line":"    def _assert_domain_is_enabled(self, domain_ref):"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAM3%2F%2B4jQ%3D","line":81,"updated":"2013-02-15 17:49:31.000000000","message":"suggest change from warning to debug. It\u0027s not abnormal for a project to be disabled.","commit_id":"1daa6bd277f91590083436bf3a729f3d1c3dc067"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"42a46fa6494857e44dae8f3521644fdb8db4125c","unresolved":false,"context_lines":[{"line_number":84,"context_line":"    def _assert_domain_is_enabled(self, domain_ref):"},{"line_number":85,"context_line":"        if not domain_ref.get(\u0027enabled\u0027, True):"},{"line_number":86,"context_line":"            msg \u003d _(\u0027Domain is disabled: %s\u0027) % (domain_ref[\u0027id\u0027])"},{"line_number":87,"context_line":"            LOG.warning(msg)"},{"line_number":88,"context_line":"            raise exception.Unauthorized(msg)"},{"line_number":89,"context_line":""},{"line_number":90,"context_line":"    def _assert_user_is_enabled(self, user_ref):"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAM3%2F%2B4i4%3D","line":87,"updated":"2013-02-15 17:49:31.000000000","message":"suggest change from warning to debug.","commit_id":"1daa6bd277f91590083436bf3a729f3d1c3dc067"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"868bc4dd0e6a2f4f936c5c785c4b16b7774112c6","unresolved":false,"context_lines":[{"line_number":84,"context_line":"    def _assert_domain_is_enabled(self, domain_ref):"},{"line_number":85,"context_line":"        if not domain_ref.get(\u0027enabled\u0027, True):"},{"line_number":86,"context_line":"            msg \u003d _(\u0027Domain is disabled: %s\u0027) % (domain_ref[\u0027id\u0027])"},{"line_number":87,"context_line":"            LOG.warning(msg)"},{"line_number":88,"context_line":"            raise exception.Unauthorized(msg)"},{"line_number":89,"context_line":""},{"line_number":90,"context_line":"    def _assert_user_is_enabled(self, user_ref):"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAM3%2F%2B4NY%3D","line":87,"in_reply_to":"AAAAM3%2F%2B4i4%3D","updated":"2013-02-15 18:38:23.000000000","message":"not sure i agree (users attempting to auth against a disabled domain should be higher than debug IMO), but either way, it\u0027s outside the scope of this change","commit_id":"1daa6bd277f91590083436bf3a729f3d1c3dc067"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"42a46fa6494857e44dae8f3521644fdb8db4125c","unresolved":false,"context_lines":[{"line_number":90,"context_line":"    def _assert_user_is_enabled(self, user_ref):"},{"line_number":91,"context_line":"        if not user_ref.get(\u0027enabled\u0027, True):"},{"line_number":92,"context_line":"            msg \u003d _(\u0027User is disabled: %s\u0027) % (user_ref[\u0027id\u0027])"},{"line_number":93,"context_line":"            LOG.warning(msg)"},{"line_number":94,"context_line":"            raise exception.Unauthorized(msg)"},{"line_number":95,"context_line":""},{"line_number":96,"context_line":"    def _lookup_domain(self, domain_info):"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAM3%2F%2B4i0%3D","line":93,"updated":"2013-02-15 17:49:31.000000000","message":"suggest change from warning to debug.","commit_id":"1daa6bd277f91590083436bf3a729f3d1c3dc067"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"42a46fa6494857e44dae8f3521644fdb8db4125c","unresolved":false,"context_lines":[{"line_number":94,"context_line":"            raise exception.Unauthorized(msg)"},{"line_number":95,"context_line":""},{"line_number":96,"context_line":"    def _lookup_domain(self, domain_info):"},{"line_number":97,"context_line":"        domain_id \u003d domain_info.get(\u0027id\u0027, None)"},{"line_number":98,"context_line":"        domain_name \u003d domain_info.get(\u0027name\u0027, None)"},{"line_number":99,"context_line":"        domain_ref \u003d None"},{"line_number":100,"context_line":"        if domain_id is None and domain_name is None:"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAM3%2F%2B4io%3D","line":97,"updated":"2013-02-15 17:49:31.000000000","message":"remove \", None\". .get returns None by default. This applies throughout this file.","commit_id":"1daa6bd277f91590083436bf3a729f3d1c3dc067"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"42a46fa6494857e44dae8f3521644fdb8db4125c","unresolved":false,"context_lines":[{"line_number":97,"context_line":"        domain_id \u003d domain_info.get(\u0027id\u0027, None)"},{"line_number":98,"context_line":"        domain_name \u003d domain_info.get(\u0027name\u0027, None)"},{"line_number":99,"context_line":"        domain_ref \u003d None"},{"line_number":100,"context_line":"        if domain_id is None and domain_name is None:"},{"line_number":101,"context_line":"            raise exception.ValidationError(attribute\u003d\u0027id or name\u0027,"},{"line_number":102,"context_line":"                                            target\u003d\u0027domain\u0027)"},{"line_number":103,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAM3%2F%2B4ig%3D","line":100,"updated":"2013-02-15 17:49:31.000000000","message":"suggest change to \"not domain_id and not domain_name\". This applies throughout this file.","commit_id":"1daa6bd277f91590083436bf3a729f3d1c3dc067"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"42a46fa6494857e44dae8f3521644fdb8db4125c","unresolved":false,"context_lines":[{"line_number":110,"context_line":"        except exception.DomainNotFound as e:"},{"line_number":111,"context_line":"            LOG.exception(e)"},{"line_number":112,"context_line":"            raise exception.Unauthorized(e)"},{"line_number":113,"context_line":"        # make sure domain is enabled"},{"line_number":114,"context_line":"        self._assert_domain_is_enabled(domain_ref)"},{"line_number":115,"context_line":"        return domain_ref"},{"line_number":116,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAM3%2F%2B4hk%3D","line":113,"updated":"2013-02-15 17:49:31.000000000","message":"remove this comment. The function name adequately explains what it does.","commit_id":"1daa6bd277f91590083436bf3a729f3d1c3dc067"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"42a46fa6494857e44dae8f3521644fdb8db4125c","unresolved":false,"context_lines":[{"line_number":136,"context_line":"        except exception.ProjectNotFound as e:"},{"line_number":137,"context_line":"            LOG.exception(e)"},{"line_number":138,"context_line":"            raise exception.Unauthorized(e)"},{"line_number":139,"context_line":"        # make sure project is enabled"},{"line_number":140,"context_line":"        self._assert_project_is_enabled(project_ref)"},{"line_number":141,"context_line":"        return project_ref"},{"line_number":142,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAM3%2F%2B4hI%3D","line":139,"updated":"2013-02-15 17:49:31.000000000","message":"remove this comment.","commit_id":"1daa6bd277f91590083436bf3a729f3d1c3dc067"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"42a46fa6494857e44dae8f3521644fdb8db4125c","unresolved":false,"context_lines":[{"line_number":162,"context_line":"        except exception.UserNotFound as e:"},{"line_number":163,"context_line":"            LOG.exception(e)"},{"line_number":164,"context_line":"            raise exception.Unauthorized(e)"},{"line_number":165,"context_line":"        # make sure user is enabled"},{"line_number":166,"context_line":"        self._assert_user_is_enabled(user_ref)"},{"line_number":167,"context_line":"        return user_ref"},{"line_number":168,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAM3%2F%2B4gg%3D","line":165,"updated":"2013-02-15 17:49:31.000000000","message":"remove this comment.","commit_id":"1daa6bd277f91590083436bf3a729f3d1c3dc067"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"42a46fa6494857e44dae8f3521644fdb8db4125c","unresolved":false,"context_lines":[{"line_number":173,"context_line":""},{"line_number":174,"context_line":"        # if scoped, only to a project or domain, but not both"},{"line_number":175,"context_line":"        if \u0027project\u0027 not in self.auth[\u0027scope\u0027] and \\"},{"line_number":176,"context_line":"           \u0027domain\u0027 not in self.auth[\u0027scope\u0027]:"},{"line_number":177,"context_line":"            # neither domain or project provided"},{"line_number":178,"context_line":"            raise exception.ValidationError(attribute\u003d\u0027project or domain\u0027,"},{"line_number":179,"context_line":"                                            target\u003d\u0027scope\u0027)"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAM3%2F%2B4eo%3D","line":176,"updated":"2013-02-15 17:49:31.000000000","message":"change \\ to use (), see https://github.com/openstack/keystone/blame/master/HACKING.rst#L14","commit_id":"1daa6bd277f91590083436bf3a729f3d1c3dc067"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"42a46fa6494857e44dae8f3521644fdb8db4125c","unresolved":false,"context_lines":[{"line_number":177,"context_line":"            # neither domain or project provided"},{"line_number":178,"context_line":"            raise exception.ValidationError(attribute\u003d\u0027project or domain\u0027,"},{"line_number":179,"context_line":"                                            target\u003d\u0027scope\u0027)"},{"line_number":180,"context_line":"        elif (\u0027project\u0027 in self.auth[\u0027scope\u0027] and"},{"line_number":181,"context_line":"              \u0027domain\u0027 in self.auth[\u0027scope\u0027]):"},{"line_number":182,"context_line":"            # both domain and project provided"},{"line_number":183,"context_line":"            raise exception.ValidationError(attribute\u003d\u0027project or domain\u0027,"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAM3%2F%2B4eI%3D","line":180,"updated":"2013-02-15 17:49:31.000000000","message":"remove \"el\", since raise would have exited the function already.","commit_id":"1daa6bd277f91590083436bf3a729f3d1c3dc067"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"42a46fa6494857e44dae8f3521644fdb8db4125c","unresolved":false,"context_lines":[{"line_number":214,"context_line":"            raise exception.ValidationError(attribute\u003d\u0027auth\u0027,"},{"line_number":215,"context_line":"                                            target\u003d\u0027request body\u0027)"},{"line_number":216,"context_line":""},{"line_number":217,"context_line":"        # validate auth methods"},{"line_number":218,"context_line":"        self._validate_auth_methods()"},{"line_number":219,"context_line":""},{"line_number":220,"context_line":"        # validate and normalize scope"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAM3%2F%2B4dY%3D","line":217,"updated":"2013-02-15 17:49:31.000000000","message":"remove this comment.","commit_id":"1daa6bd277f91590083436bf3a729f3d1c3dc067"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"42a46fa6494857e44dae8f3521644fdb8db4125c","unresolved":false,"context_lines":[{"line_number":217,"context_line":"        # validate auth methods"},{"line_number":218,"context_line":"        self._validate_auth_methods()"},{"line_number":219,"context_line":""},{"line_number":220,"context_line":"        # validate and normalize scope"},{"line_number":221,"context_line":"        self._validate_and_normalize_scope_data()"},{"line_number":222,"context_line":""},{"line_number":223,"context_line":"    def get_method_names(self):"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAM3%2F%2B4dU%3D","line":220,"updated":"2013-02-15 17:49:31.000000000","message":"remove this comment.","commit_id":"1daa6bd277f91590083436bf3a729f3d1c3dc067"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"42a46fa6494857e44dae8f3521644fdb8db4125c","unresolved":false,"context_lines":[{"line_number":253,"context_line":""},{"line_number":254,"context_line":"    def set_scope(self, domain_id\u003dNone, project_id\u003dNone):"},{"line_number":255,"context_line":"        \"\"\" Set scope information. \"\"\""},{"line_number":256,"context_line":"        self._scope_data \u003d (domain_id, project_id)"},{"line_number":257,"context_line":""},{"line_number":258,"context_line":""},{"line_number":259,"context_line":"class Auth(controller.V3Controller):"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAM3%2F%2B4dI%3D","line":256,"updated":"2013-02-15 17:49:31.000000000","message":"should this validate that only 1 of domain_id or project_id is set?","commit_id":"1daa6bd277f91590083436bf3a729f3d1c3dc067"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"42a46fa6494857e44dae8f3521644fdb8db4125c","unresolved":false,"context_lines":[{"line_number":275,"context_line":"            self.authenticate(context, auth_info, auth_context)"},{"line_number":276,"context_line":"            self._check_and_set_default_scoping(context, auth_info,"},{"line_number":277,"context_line":"                                                auth_context)"},{"line_number":278,"context_line":"            (token_id, token_data) \u003d \\"},{"line_number":279,"context_line":"                token_factory.create_token(context, auth_context, auth_info)"},{"line_number":280,"context_line":"            return token_factory.render_token_data_response(token_id,"},{"line_number":281,"context_line":"                                                            token_data)"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAM3%2F%2B4c8%3D","line":278,"updated":"2013-02-15 17:49:31.000000000","message":"Use () rather than \\. https://github.com/openstack/keystone/blame/master/HACKING.rst#L14","commit_id":"1daa6bd277f91590083436bf3a729f3d1c3dc067"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"42a46fa6494857e44dae8f3521644fdb8db4125c","unresolved":false,"context_lines":[{"line_number":285,"context_line":"            raise e"},{"line_number":286,"context_line":"        except Exception as ae:"},{"line_number":287,"context_line":"            LOG.exception(ae)"},{"line_number":288,"context_line":"            raise exception.Unauthorized(ae)"},{"line_number":289,"context_line":""},{"line_number":290,"context_line":"    def _check_and_set_default_scoping(self, context, auth_info, auth_context):"},{"line_number":291,"context_line":"        (domain_id, project_id) \u003d auth_info.get_scope()"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAM3%2F%2B4c0%3D","line":288,"updated":"2013-02-15 17:49:31.000000000","message":"It seems like every exception turns into Unauthorized... is it possible to get Internal Server Error if there\u0027s some kind of internal server error?","commit_id":"1daa6bd277f91590083436bf3a729f3d1c3dc067"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"42a46fa6494857e44dae8f3521644fdb8db4125c","unresolved":false,"context_lines":[{"line_number":299,"context_line":"                context\u003dcontext, user_id\u003dauth_context[\u0027user_id\u0027])"},{"line_number":300,"context_line":"            default_project_id \u003d user_ref.get(\u0027default_project_id\u0027, None)"},{"line_number":301,"context_line":"            if default_project_id:"},{"line_number":302,"context_line":"                auth_info.set_scope(None, default_project_id)"},{"line_number":303,"context_line":"        except exception.UserNotFound as e:"},{"line_number":304,"context_line":"            LOG.exception(e)"},{"line_number":305,"context_line":"            raise exception.Unauthorized(e)"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAM3%2F%2B4cA%3D","line":302,"updated":"2013-02-15 17:49:31.000000000","message":"these are named parameters, so should be \"domain_id\u003dNone, project_id\u003ddefault_project_id\", or \"project_id\u003ddefault_project_id\"","commit_id":"1daa6bd277f91590083436bf3a729f3d1c3dc067"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"42a46fa6494857e44dae8f3521644fdb8db4125c","unresolved":false,"context_lines":[{"line_number":311,"context_line":"        # requiring domain_id to do user lookup now. Try to get"},{"line_number":312,"context_line":"        # the user_id from auth_info for now, assuming external auth"},{"line_number":313,"context_line":"        # has check to make sure user is the same as the one specify"},{"line_number":314,"context_line":"        # in \"authentication\"."},{"line_number":315,"context_line":"        if \u0027password\u0027 in auth_info.get_method_names():"},{"line_number":316,"context_line":"            user_info \u003d auth_info.get_method_data(\u0027password\u0027)"},{"line_number":317,"context_line":"            user_ref \u003d auth_info.lookup_user(user_info[\u0027user\u0027])"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAM3%2F%2B4bw%3D","line":314,"updated":"2013-02-15 17:49:31.000000000","message":"seems like we need a default domain for remote users?","commit_id":"1daa6bd277f91590083436bf3a729f3d1c3dc067"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"42a46fa6494857e44dae8f3521644fdb8db4125c","unresolved":false,"context_lines":[{"line_number":327,"context_line":"        if \u0027REMOTE_USER\u0027 in context:"},{"line_number":328,"context_line":"            return self._build_remote_user_auth_context(context,"},{"line_number":329,"context_line":"                                                        auth_info,"},{"line_number":330,"context_line":"                                                        auth_context)"},{"line_number":331,"context_line":""},{"line_number":332,"context_line":"        # need to aggregate the results in case two or more methods"},{"line_number":333,"context_line":"        # are specified"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAM3%2F%2B4a0%3D","line":330,"updated":"2013-02-15 17:49:31.000000000","message":"_build_remote_user_auth_context doesn\u0027t return anything. suggest change to \n\n self._build_remote_user_auth_context(context, auth_info, auth_context)\n return","commit_id":"1daa6bd277f91590083436bf3a729f3d1c3dc067"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"42a46fa6494857e44dae8f3521644fdb8db4125c","unresolved":false,"context_lines":[{"line_number":331,"context_line":""},{"line_number":332,"context_line":"        # need to aggregate the results in case two or more methods"},{"line_number":333,"context_line":"        # are specified"},{"line_number":334,"context_line":"        auth_response \u003d {\"methods\": []}"},{"line_number":335,"context_line":"        for method_name in auth_info.get_method_names():"},{"line_number":336,"context_line":"            method \u003d get_auth_method(method_name)"},{"line_number":337,"context_line":"            resp \u003d method.authenticate(context, auth_info, auth_context)"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAM3%2F%2B4bA%3D","line":334,"updated":"2013-02-15 17:49:31.000000000","message":"\" -\u003e \u0027 , see https://github.com/openstack/keystone/blame/master/HACKING.rst#L20","commit_id":"1daa6bd277f91590083436bf3a729f3d1c3dc067"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"42a46fa6494857e44dae8f3521644fdb8db4125c","unresolved":false,"context_lines":[{"line_number":335,"context_line":"        for method_name in auth_info.get_method_names():"},{"line_number":336,"context_line":"            method \u003d get_auth_method(method_name)"},{"line_number":337,"context_line":"            resp \u003d method.authenticate(context, auth_info, auth_context)"},{"line_number":338,"context_line":"            if resp is not None:"},{"line_number":339,"context_line":"                auth_response[\u0027methods\u0027].append(method_name)"},{"line_number":340,"context_line":"                auth_response[method_name] \u003d resp"},{"line_number":341,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAM3%2F%2B4bg%3D","line":338,"updated":"2013-02-15 17:49:31.000000000","message":"remove \"is not None\"","commit_id":"1daa6bd277f91590083436bf3a729f3d1c3dc067"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"42a46fa6494857e44dae8f3521644fdb8db4125c","unresolved":false,"context_lines":[{"line_number":337,"context_line":"            resp \u003d method.authenticate(context, auth_info, auth_context)"},{"line_number":338,"context_line":"            if resp is not None:"},{"line_number":339,"context_line":"                auth_response[\u0027methods\u0027].append(method_name)"},{"line_number":340,"context_line":"                auth_response[method_name] \u003d resp"},{"line_number":341,"context_line":""},{"line_number":342,"context_line":"        if len(auth_response[\"methods\"]) \u003e 0:"},{"line_number":343,"context_line":"            # authenticatin continuation required"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAM3%2F%2B4aY%3D","line":340,"updated":"2013-02-15 17:49:31.000000000","message":"do we need to maintain auth_response[\u0027methods\u0027]? seems like it\u0027s equivalent to auth_response.keys().","commit_id":"1daa6bd277f91590083436bf3a729f3d1c3dc067"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"42a46fa6494857e44dae8f3521644fdb8db4125c","unresolved":false,"context_lines":[{"line_number":338,"context_line":"            if resp is not None:"},{"line_number":339,"context_line":"                auth_response[\u0027methods\u0027].append(method_name)"},{"line_number":340,"context_line":"                auth_response[method_name] \u003d resp"},{"line_number":341,"context_line":""},{"line_number":342,"context_line":"        if len(auth_response[\"methods\"]) \u003e 0:"},{"line_number":343,"context_line":"            # authenticatin continuation required"},{"line_number":344,"context_line":"            raise exception.AdditionalAuthRequired(auth_response)"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAM3%2F%2B4Xw%3D","line":341,"updated":"2013-02-15 17:49:31.000000000","message":"if resp is None, should assert auth_context[\u0027user_id\u0027] is set since the docs say the function must set it.","commit_id":"1daa6bd277f91590083436bf3a729f3d1c3dc067"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"42a46fa6494857e44dae8f3521644fdb8db4125c","unresolved":false,"context_lines":[{"line_number":340,"context_line":"                auth_response[method_name] \u003d resp"},{"line_number":341,"context_line":""},{"line_number":342,"context_line":"        if len(auth_response[\"methods\"]) \u003e 0:"},{"line_number":343,"context_line":"            # authenticatin continuation required"},{"line_number":344,"context_line":"            raise exception.AdditionalAuthRequired(auth_response)"},{"line_number":345,"context_line":""},{"line_number":346,"context_line":"    def _get_token_ref(self, context, token_id, belongs_to\u003dNone):"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAM3%2F%2B4bU%3D","line":343,"updated":"2013-02-15 17:49:31.000000000","message":"remove this comment, or \"authenticatin\" -\u003e \"authentication\"","commit_id":"1daa6bd277f91590083436bf3a729f3d1c3dc067"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"42a46fa6494857e44dae8f3521644fdb8db4125c","unresolved":false,"context_lines":[{"line_number":345,"context_line":""},{"line_number":346,"context_line":"    def _get_token_ref(self, context, token_id, belongs_to\u003dNone):"},{"line_number":347,"context_line":"        # FIXME(gyee): looks like a security bug in v2 token API?"},{"line_number":348,"context_line":"        # we need to check to make sure the token is still valid first"},{"line_number":349,"context_line":"        token_ref \u003d self.token_api.get_token(context\u003dcontext,"},{"line_number":350,"context_line":"                                             token_id\u003dtoken_id)"},{"line_number":351,"context_line":"        if cms.is_ans1_token(token_id):"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAM3%2F%2B4aE%3D","line":348,"updated":"2013-02-15 17:49:31.000000000","message":"sounds like a pretty major bug!","commit_id":"1daa6bd277f91590083436bf3a729f3d1c3dc067"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"b7153890402c9ef72b81e981115d1de11a9474df","unresolved":false,"context_lines":[{"line_number":345,"context_line":""},{"line_number":346,"context_line":"    def _get_token_ref(self, context, token_id, belongs_to\u003dNone):"},{"line_number":347,"context_line":"        # FIXME(gyee): looks like a security bug in v2 token API?"},{"line_number":348,"context_line":"        # we need to check to make sure the token is still valid first"},{"line_number":349,"context_line":"        token_ref \u003d self.token_api.get_token(context\u003dcontext,"},{"line_number":350,"context_line":"                                             token_id\u003dtoken_id)"},{"line_number":351,"context_line":"        if cms.is_ans1_token(token_id):"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAM3%2F%2B4Bs%3D","line":348,"in_reply_to":"AAAAM3%2F%2B4aE%3D","updated":"2013-02-15 19:55:42.000000000","message":"I am about to file a security bug against Keystone V2. For PKI tokens, we don\u0027t seem to check the validity of the token first.","commit_id":"1daa6bd277f91590083436bf3a729f3d1c3dc067"},{"author":{"_account_id":2218,"name":"Adam Young","email":"adam@younglogic.com","username":"ayoung"},"change_message_id":"f7c5b5bba57e4077a7700fa85ac89a273661480d","unresolved":false,"context_lines":[{"line_number":304,"context_line":"    def _build_remote_user_auth_context(self, context, auth_info,"},{"line_number":305,"context_line":"                                        auth_context):"},{"line_number":306,"context_line":"        username \u003d context[\u0027REMOTE_USER\u0027]"},{"line_number":307,"context_line":"        # FIXME(gyee): REMOTE_USER is not good enough since we are"},{"line_number":308,"context_line":"        # requiring domain_id to do user lookup now. Try to get"},{"line_number":309,"context_line":"        # the user_id from auth_info for now, assuming external auth"},{"line_number":310,"context_line":"        # has check to make sure user is the same as the one specify"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAM3%2F%2B2Vw%3D","line":307,"updated":"2013-02-17 06:22:28.000000000","message":"would a domain suffix field be a usable alternative here?  For each domain, if they provide a suffix,  see if it matches the username.  If so, the user belongs to that domain.","commit_id":"25e13fffbfc512595c1ca19fd378df7d21745056"},{"author":{"_account_id":2218,"name":"Adam Young","email":"adam@younglogic.com","username":"ayoung"},"change_message_id":"f7c5b5bba57e4077a7700fa85ac89a273661480d","unresolved":false,"context_lines":[{"line_number":346,"context_line":"            raise exception.Unauthorized(msg)"},{"line_number":347,"context_line":""},{"line_number":348,"context_line":"    def _get_token_ref(self, context, token_id, belongs_to\u003dNone):"},{"line_number":349,"context_line":"        # FIXME(gyee): looks like a security bug in v2 token API?"},{"line_number":350,"context_line":"        # we need to check to make sure the token is still valid first"},{"line_number":351,"context_line":"        token_ref \u003d self.token_api.get_token(context\u003dcontext,"},{"line_number":352,"context_line":"                                             token_id\u003dtoken_id)"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAM3%2F%2B2Vs%3D","line":349,"updated":"2013-02-17 06:22:28.000000000","message":"NO, as revoked tokens will not be returned from a list or get call.","commit_id":"25e13fffbfc512595c1ca19fd378df7d21745056"},{"author":{"_account_id":2340,"name":"Ionut Artarisi","email":"iartarisi@suse.cz","username":"mapleoin"},"change_message_id":"c4f6949efd7663cde129c633aa34e079d3facc46","unresolved":false,"context_lines":[{"line_number":279,"context_line":"                exception.AuthMethodNotSupported,"},{"line_number":280,"context_line":"                exception.AdditionalAuthRequired) as e:"},{"line_number":281,"context_line":"            raise e"},{"line_number":282,"context_line":"        except Exception as ae:"},{"line_number":283,"context_line":"            LOG.exception(ae)"},{"line_number":284,"context_line":"            raise exception.Unauthorized(ae)"},{"line_number":285,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAM3%2F%2Bx54%3D","line":282,"updated":"2013-02-19 15:10:53.000000000","message":"The \u0027ae\u0027 here is really not necessary, \u0027e\u0027 would\u0027ve been fine. The other \u0027e\u0027 is in a different scope.","commit_id":"6c6df626dcc0773c7ae4e8378efdbf8f36763858"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"2482acfca99e63c8b13431418965f283ff60a511","unresolved":false,"context_lines":[{"line_number":19,"context_line":"from keystone.auth import token_factory"},{"line_number":20,"context_line":"from keystone.common import controller"},{"line_number":21,"context_line":"from keystone.common import cms"},{"line_number":22,"context_line":"from keystone.common import dependency"},{"line_number":23,"context_line":"from keystone.common import logging"},{"line_number":24,"context_line":"from keystone import config"},{"line_number":25,"context_line":"from keystone import exception"}],"source_content_type":"text/x-python","patch_set":14,"id":"AAAAM3%2F%2BwhY%3D","line":22,"updated":"2013-02-19 21:00:16.000000000","message":"unused?","commit_id":"2823e852c387292387ce35087af92491ac11b472"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"2482acfca99e63c8b13431418965f283ff60a511","unresolved":false,"context_lines":[{"line_number":228,"context_line":""},{"line_number":229,"context_line":"        \"\"\""},{"line_number":230,"context_line":"        if method not in self.auth[\u0027authentication\u0027][\u0027methods\u0027]:"},{"line_number":231,"context_line":"            raise AuthenticationMethodNotFound(method)"},{"line_number":232,"context_line":"        return self.auth[\u0027authentication\u0027][method]"},{"line_number":233,"context_line":""},{"line_number":234,"context_line":"    def get_scope(self):"}],"source_content_type":"text/x-python","patch_set":14,"id":"AAAAM3%2F%2Bwho%3D","line":231,"updated":"2013-02-19 21:00:16.000000000","message":"undefined","commit_id":"2823e852c387292387ce35087af92491ac11b472"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"679493cb2d192acb759943ea7ffe91dd5e83fcaf","unresolved":false,"context_lines":[{"line_number":227,"context_line":""},{"line_number":228,"context_line":"        \"\"\""},{"line_number":229,"context_line":"        if method not in self.auth[\u0027authentication\u0027][\u0027methods\u0027]:"},{"line_number":230,"context_line":"            raise AuthenticationMethodNotFound(method)"},{"line_number":231,"context_line":"        return self.auth[\u0027authentication\u0027][method]"},{"line_number":232,"context_line":""},{"line_number":233,"context_line":"    def get_scope(self):"}],"source_content_type":"text/x-python","patch_set":21,"id":"AAAAM3%2F%2BuRQ%3D","line":230,"updated":"2013-02-20 18:22:18.000000000","message":"this isn\u0027t defined","commit_id":"e6300fd4c697ba676afb98e0f5a5dcdb2d5c575d"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"07ef9c5ac0fd5b3f5c4db862a798fd8bae13bba8","unresolved":false,"context_lines":[{"line_number":227,"context_line":""},{"line_number":228,"context_line":"        \"\"\""},{"line_number":229,"context_line":"        if method not in self.auth[\u0027authentication\u0027][\u0027methods\u0027]:"},{"line_number":230,"context_line":"            raise AuthenticationMethodNotFound(method)"},{"line_number":231,"context_line":"        return self.auth[\u0027authentication\u0027][method]"},{"line_number":232,"context_line":""},{"line_number":233,"context_line":"    def get_scope(self):"}],"source_content_type":"text/x-python","patch_set":21,"id":"AAAAM3%2F%2BuME%3D","line":230,"in_reply_to":"AAAAM3%2F%2BuRQ%3D","updated":"2013-02-20 18:41:17.000000000","message":"Good catch!","commit_id":"e6300fd4c697ba676afb98e0f5a5dcdb2d5c575d"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"95daf4445fe6a95d9a5da811f8f5e25f68ffd787","unresolved":false,"context_lines":[{"line_number":256,"context_line":"        super(Auth, self).__init__(*args, **kw)"},{"line_number":257,"context_line":"        self.token_controllers_ref \u003d token.controllers.Auth()"},{"line_number":258,"context_line":""},{"line_number":259,"context_line":"    def authenticate_for_token(self, context, authentication\u003dNone, scope\u003dNone):"},{"line_number":260,"context_line":"        \"\"\" Authenticate user and issue a token. \"\"\""},{"line_number":261,"context_line":"        try:"},{"line_number":262,"context_line":"            auth \u003d None"}],"source_content_type":"text/x-python","patch_set":21,"id":"AAAAM3%2F%2BuKw%3D","line":259,"updated":"2013-02-20 18:48:21.000000000","message":"authentication should not be optional\n\nif it\u0027s not provided, the keystone.common.wsgi.Application will raise a 400","commit_id":"e6300fd4c697ba676afb98e0f5a5dcdb2d5c575d"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"95daf4445fe6a95d9a5da811f8f5e25f68ffd787","unresolved":false,"context_lines":[{"line_number":260,"context_line":"        \"\"\" Authenticate user and issue a token. \"\"\""},{"line_number":261,"context_line":"        try:"},{"line_number":262,"context_line":"            auth \u003d None"},{"line_number":263,"context_line":"            if authentication:"},{"line_number":264,"context_line":"                auth \u003d {\u0027authentication\u0027: authentication}"},{"line_number":265,"context_line":"                if scope:"},{"line_number":266,"context_line":"                    auth[\u0027scope\u0027] \u003d scope"}],"source_content_type":"text/x-python","patch_set":21,"id":"AAAAM3%2F%2BuKc%3D","line":263,"updated":"2013-02-20 18:48:21.000000000","message":"authentication is not optional","commit_id":"e6300fd4c697ba676afb98e0f5a5dcdb2d5c575d"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"95daf4445fe6a95d9a5da811f8f5e25f68ffd787","unresolved":false,"context_lines":[{"line_number":261,"context_line":"        try:"},{"line_number":262,"context_line":"            auth \u003d None"},{"line_number":263,"context_line":"            if authentication:"},{"line_number":264,"context_line":"                auth \u003d {\u0027authentication\u0027: authentication}"},{"line_number":265,"context_line":"                if scope:"},{"line_number":266,"context_line":"                    auth[\u0027scope\u0027] \u003d scope"},{"line_number":267,"context_line":"            auth_info \u003d AuthInfo(context, auth\u003dauth)"}],"source_content_type":"text/x-python","patch_set":21,"id":"AAAAM3%2F%2BuKU%3D","line":264,"updated":"2013-02-20 18:48:21.000000000","message":"the framework just unpacked this value... why are you repacking it?","commit_id":"e6300fd4c697ba676afb98e0f5a5dcdb2d5c575d"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"b3041992d2d98281fd8048a890e8538a5af7c1c2","unresolved":false,"context_lines":[{"line_number":261,"context_line":"        try:"},{"line_number":262,"context_line":"            auth \u003d None"},{"line_number":263,"context_line":"            if authentication:"},{"line_number":264,"context_line":"                auth \u003d {\u0027authentication\u0027: authentication}"},{"line_number":265,"context_line":"                if scope:"},{"line_number":266,"context_line":"                    auth[\u0027scope\u0027] \u003d scope"},{"line_number":267,"context_line":"            auth_info \u003d AuthInfo(context, auth\u003dauth)"}],"source_content_type":"text/x-python","patch_set":21,"id":"AAAAM3%2F%2BuJY%3D","line":264,"in_reply_to":"AAAAM3%2F%2BuKU%3D","updated":"2013-02-20 18:51:55.000000000","message":"I need it construct the AuthInfo object.","commit_id":"e6300fd4c697ba676afb98e0f5a5dcdb2d5c575d"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"c09d3e75671b016dff9278ee3eccc9ecaaf587bd","unresolved":false,"context_lines":[{"line_number":265,"context_line":"                if scope:"},{"line_number":266,"context_line":"                    auth[\u0027scope\u0027] \u003d scope"},{"line_number":267,"context_line":"            auth_info \u003d AuthInfo(context, auth\u003dauth)"},{"line_number":268,"context_line":"            auth_context \u003d {\u0027extras\u0027: {}, \u0027method_names\u0027: []}"},{"line_number":269,"context_line":"            self.authenticate(context, auth_info, auth_context)"},{"line_number":270,"context_line":"            self._check_and_set_default_scoping(context, auth_info,"},{"line_number":271,"context_line":"                                                auth_context)"}],"source_content_type":"text/x-python","patch_set":21,"id":"AAAAM3%2F%2BuS4%3D","line":268,"updated":"2013-02-20 18:20:44.000000000","message":"remove extras","commit_id":"e6300fd4c697ba676afb98e0f5a5dcdb2d5c575d"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"884a5245bec445e4189a1a6ae6d23fbceec32b96","unresolved":false,"context_lines":[{"line_number":265,"context_line":"                if scope:"},{"line_number":266,"context_line":"                    auth[\u0027scope\u0027] \u003d scope"},{"line_number":267,"context_line":"            auth_info \u003d AuthInfo(context, auth\u003dauth)"},{"line_number":268,"context_line":"            auth_context \u003d {\u0027extras\u0027: {}, \u0027method_names\u0027: []}"},{"line_number":269,"context_line":"            self.authenticate(context, auth_info, auth_context)"},{"line_number":270,"context_line":"            self._check_and_set_default_scoping(context, auth_info,"},{"line_number":271,"context_line":"                                                auth_context)"}],"source_content_type":"text/x-python","patch_set":21,"id":"AAAAM3%2F%2BuM0%3D","line":268,"in_reply_to":"AAAAM3%2F%2BuQM%3D","updated":"2013-02-20 18:39:07.000000000","message":"Thought we agreed on having the \"extras\" attribute in the token to carry any deployment-specific data. Data in \"extras\" are provided by the plugins.","commit_id":"e6300fd4c697ba676afb98e0f5a5dcdb2d5c575d"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"d744dccbf23b779a95fb16e663edb1ff1a2f2bc8","unresolved":false,"context_lines":[{"line_number":265,"context_line":"                if scope:"},{"line_number":266,"context_line":"                    auth[\u0027scope\u0027] \u003d scope"},{"line_number":267,"context_line":"            auth_info \u003d AuthInfo(context, auth\u003dauth)"},{"line_number":268,"context_line":"            auth_context \u003d {\u0027extras\u0027: {}, \u0027method_names\u0027: []}"},{"line_number":269,"context_line":"            self.authenticate(context, auth_info, auth_context)"},{"line_number":270,"context_line":"            self._check_and_set_default_scoping(context, auth_info,"},{"line_number":271,"context_line":"                                                auth_context)"}],"source_content_type":"text/x-python","patch_set":21,"id":"AAAAM3%2F%2BuQM%3D","line":268,"in_reply_to":"AAAAM3%2F%2BuQU%3D","updated":"2013-02-20 18:29:12.000000000","message":"it\u0027s not in the spec, i\u0027ve never seen it documented and it doesn\u0027t look like you\u0027re using it here either","commit_id":"e6300fd4c697ba676afb98e0f5a5dcdb2d5c575d"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"fcd9c4c002ac559083a50cea5ea5059fd92f8560","unresolved":false,"context_lines":[{"line_number":265,"context_line":"                if scope:"},{"line_number":266,"context_line":"                    auth[\u0027scope\u0027] \u003d scope"},{"line_number":267,"context_line":"            auth_info \u003d AuthInfo(context, auth\u003dauth)"},{"line_number":268,"context_line":"            auth_context \u003d {\u0027extras\u0027: {}, \u0027method_names\u0027: []}"},{"line_number":269,"context_line":"            self.authenticate(context, auth_info, auth_context)"},{"line_number":270,"context_line":"            self._check_and_set_default_scoping(context, auth_info,"},{"line_number":271,"context_line":"                                                auth_context)"}],"source_content_type":"text/x-python","patch_set":21,"id":"AAAAM3%2F%2BuQU%3D","line":268,"in_reply_to":"AAAAM3%2F%2BuS4%3D","updated":"2013-02-20 18:26:27.000000000","message":"why? thought we have the extras in our design.","commit_id":"e6300fd4c697ba676afb98e0f5a5dcdb2d5c575d"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"c18c4895cc4620c411aa50f230eb098a0f868931","unresolved":false,"context_lines":[{"line_number":306,"context_line":"        # requiring domain_id to do user lookup now. Try to get"},{"line_number":307,"context_line":"        # the user_id from auth_info for now, assuming external auth"},{"line_number":308,"context_line":"        # has check to make sure user is the same as the one specify"},{"line_number":309,"context_line":"        # in \"authentication\"."},{"line_number":310,"context_line":"        if \u0027password\u0027 in auth_info.get_method_names():"},{"line_number":311,"context_line":"            user_info \u003d auth_info.get_method_data(\u0027password\u0027)"},{"line_number":312,"context_line":"            user_ref \u003d auth_info.lookup_user(user_info[\u0027user\u0027])"}],"source_content_type":"text/x-python","patch_set":21,"id":"AAAAM3%2F%2BuJk%3D","line":309,"updated":"2013-02-20 18:51:33.000000000","message":"remote_user should provide a user_id, not a user name\n\nif it\u0027s going to a provide a username, then we have to assume default domain","commit_id":"e6300fd4c697ba676afb98e0f5a5dcdb2d5c575d"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"c18c4895cc4620c411aa50f230eb098a0f868931","unresolved":false,"context_lines":[{"line_number":312,"context_line":"            user_ref \u003d auth_info.lookup_user(user_info[\u0027user\u0027])"},{"line_number":313,"context_line":"            auth_context[\u0027user_id\u0027] \u003d user_ref[\u0027id\u0027]"},{"line_number":314,"context_line":"        else:"},{"line_number":315,"context_line":"            msg \u003d _(\u0027Unable to lookup user %s\u0027) % (username)"},{"line_number":316,"context_line":"            raise exception.Unauthorized(msg)"},{"line_number":317,"context_line":""},{"line_number":318,"context_line":"    def authenticate(self, context, auth_info, auth_context):"}],"source_content_type":"text/x-python","patch_set":21,"id":"AAAAM3%2F%2BuJU%3D","line":315,"updated":"2013-02-20 18:51:33.000000000","message":"i don\u0027t quite understand why REMOTE_USER requires a password plugin, and the error message doesn\u0027t really indicate what\u0027s wrong -- this should almost be an 500 exception.UnexpectedError, not a 401","commit_id":"e6300fd4c697ba676afb98e0f5a5dcdb2d5c575d"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"c09d3e75671b016dff9278ee3eccc9ecaaf587bd","unresolved":false,"context_lines":[{"line_number":339,"context_line":""},{"line_number":340,"context_line":"        if len(auth_response[\"methods\"]) \u003e 0:"},{"line_number":341,"context_line":"            # authentication continuation required"},{"line_number":342,"context_line":"            raise exception.AdditionalAuthRequired(auth_response)"},{"line_number":343,"context_line":""},{"line_number":344,"context_line":"        if \u0027user_id\u0027 not in auth_context:"},{"line_number":345,"context_line":"            msg \u003d _(\u0027User not found\u0027)"}],"source_content_type":"text/x-python","patch_set":21,"id":"AAAAM3%2F%2BuRs%3D","line":342,"updated":"2013-02-20 18:20:44.000000000","message":"help me understand this check... if at least one auth method succeeded... raise an exception that you need more?","commit_id":"e6300fd4c697ba676afb98e0f5a5dcdb2d5c575d"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"07ef9c5ac0fd5b3f5c4db862a798fd8bae13bba8","unresolved":false,"context_lines":[{"line_number":339,"context_line":""},{"line_number":340,"context_line":"        if len(auth_response[\"methods\"]) \u003e 0:"},{"line_number":341,"context_line":"            # authentication continuation required"},{"line_number":342,"context_line":"            raise exception.AdditionalAuthRequired(auth_response)"},{"line_number":343,"context_line":""},{"line_number":344,"context_line":"        if \u0027user_id\u0027 not in auth_context:"},{"line_number":345,"context_line":"            msg \u003d _(\u0027User not found\u0027)"}],"source_content_type":"text/x-python","patch_set":21,"id":"AAAAM3%2F%2BuMI%3D","line":342,"in_reply_to":"AAAAM3%2F%2BuPA%3D","updated":"2013-02-20 18:41:17.000000000","message":"We need to aggregate all the continuation responses. I\u0027ve documented the expected behavior in both configuration.rst and the AuthPluginHander interface.","commit_id":"e6300fd4c697ba676afb98e0f5a5dcdb2d5c575d"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"d744dccbf23b779a95fb16e663edb1ff1a2f2bc8","unresolved":false,"context_lines":[{"line_number":339,"context_line":""},{"line_number":340,"context_line":"        if len(auth_response[\"methods\"]) \u003e 0:"},{"line_number":341,"context_line":"            # authentication continuation required"},{"line_number":342,"context_line":"            raise exception.AdditionalAuthRequired(auth_response)"},{"line_number":343,"context_line":""},{"line_number":344,"context_line":"        if \u0027user_id\u0027 not in auth_context:"},{"line_number":345,"context_line":"            msg \u003d _(\u0027User not found\u0027)"}],"source_content_type":"text/x-python","patch_set":21,"id":"AAAAM3%2F%2BuPA%3D","line":342,"in_reply_to":"AAAAM3%2F%2BuQc%3D","updated":"2013-02-20 18:29:12.000000000","message":"i don\u0027t understand how the condition in the \u0027if\u0027 statement is capable of making that determination? I think I would expect the plugin to raise AdditonalAuthRequired and this code to allow that to bubble back to the API?","commit_id":"e6300fd4c697ba676afb98e0f5a5dcdb2d5c575d"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"fcd9c4c002ac559083a50cea5ea5059fd92f8560","unresolved":false,"context_lines":[{"line_number":339,"context_line":""},{"line_number":340,"context_line":"        if len(auth_response[\"methods\"]) \u003e 0:"},{"line_number":341,"context_line":"            # authentication continuation required"},{"line_number":342,"context_line":"            raise exception.AdditionalAuthRequired(auth_response)"},{"line_number":343,"context_line":""},{"line_number":344,"context_line":"        if \u0027user_id\u0027 not in auth_context:"},{"line_number":345,"context_line":"            msg \u003d _(\u0027User not found\u0027)"}],"source_content_type":"text/x-python","patch_set":21,"id":"AAAAM3%2F%2BuQc%3D","line":342,"in_reply_to":"AAAAM3%2F%2BuRs%3D","updated":"2013-02-20 18:26:27.000000000","message":"an authentication is consider successful if all methods are succeeded. If one or more methods need continuation, then return a 401 with the information needed for the next authentication step.\n\nSay we have three methods: password, rsa, challenge-response\n\npassword succeeded, but rsa needs next token code and challenge-response issue a challenge, we would raise an AdditionalAuthRequired exception with the payload from rsa and challenge-response.","commit_id":"e6300fd4c697ba676afb98e0f5a5dcdb2d5c575d"}],"keystone/auth/core.py":[{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"bbc81e0d674e56c142aceb4c518a1a51eea27aba","unresolved":false,"context_lines":[{"line_number":34,"context_line":"        If success, auth plugin must provide \"user_id\" in auth_context. Auth"},{"line_number":35,"context_line":"        plugin may optionally add any addition methods into the \"method_names\""},{"line_number":36,"context_line":"        list. For example, if the authentiation is for rescoping, auth method"},{"line_number":37,"context_line":"        must append the previous method names into \"method_names\". Also, auth"},{"line_number":38,"context_line":"        plugin may add any addition information into the \"extras\" dictionary"},{"line_number":39,"context_line":"        in the auth_context. Anything in \"extras\" will be conveyed in the"},{"line_number":40,"context_line":"        token\u0027s extras field."}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2FDyo%3D","line":37,"updated":"2013-02-08 17:42:43.000000000","message":"if you\u0027re giving the plugin full access to the list, you should just say the plugin is free to manipulate the list of methods as appropriate, and is expected to append itself to the list.\n\nif it should be a strict contract of append-only, it should return a new list to be appended","commit_id":"f03a5dc460399d89064cce9ecf521fad55e26a3a"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"03e156601c97b1b200e8a6e877079ef97fcb25a8","unresolved":false,"context_lines":[{"line_number":34,"context_line":"        If success, auth plugin must provide \"user_id\" in auth_context. Auth"},{"line_number":35,"context_line":"        plugin may optionally add any addition methods into the \"method_names\""},{"line_number":36,"context_line":"        list. For example, if the authentiation is for rescoping, auth method"},{"line_number":37,"context_line":"        must append the previous method names into \"method_names\". Also, auth"},{"line_number":38,"context_line":"        plugin may add any addition information into the \"extras\" dictionary"},{"line_number":39,"context_line":"        in the auth_context. Anything in \"extras\" will be conveyed in the"},{"line_number":40,"context_line":"        token\u0027s extras field."}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2FDjY%3D","line":37,"in_reply_to":"AAAAM3%2F%2FDyo%3D","updated":"2013-02-08 19:27:44.000000000","message":"plugins have full access to the list and they should make whatever modifications deemed necessary. This is a better approach because plugins may need to coordinate with one another to a certain degree. The downside is plugin can corrupted the context.\n\nMy experience is that any 3rd plugin to be deployed in an enterprise is subject to intense scrutiny anyway. Static analysis, code review, etc. The whole 9 yard.","commit_id":"f03a5dc460399d89064cce9ecf521fad55e26a3a"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"0cc06797a3047b1f3e48cbeb7b3faf0c09fd22af","unresolved":false,"context_lines":[{"line_number":23,"context_line":"    \"\"\"Abstract base class for an authentication plugin.\"\"\""},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"    def __init__(self):"},{"line_number":26,"context_line":"        pass"},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"    def authenticate(self, context, auth_info, auth_context):"},{"line_number":29,"context_line":"        \"\"\" Authenticate user and return an authentication context."}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAAM3%2F%2B%2B8A%3D","line":26,"updated":"2013-02-12 15:42:20.000000000","message":"is this the fix to the dependency injection issue?","commit_id":"026f19ee81eeb09f1aba9c287189495627e833aa"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"9ce505bf13c6427c10eeebad527910d1bd91e9df","unresolved":false,"context_lines":[{"line_number":34,"context_line":"        :auth_context: user authentication context, a dictionary shared"},{"line_number":35,"context_line":"                       by all plugins"},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"        If success, auth plugin must provide a valid \"user_id\" in"},{"line_number":38,"context_line":"        auth_context. Auth plugin may optionally add any addition methods"},{"line_number":39,"context_line":"        into the \"method_names\""},{"line_number":40,"context_line":"        list. For example, if the authentiation is for rescoping, auth method"}],"source_content_type":"text/x-python","patch_set":6,"id":"AAAAM3%2F%2B6WA%3D","line":37,"updated":"2013-02-14 18:09:34.000000000","message":"success-\u003e successful\n\nalthough i feel like the docs written seperately are a bit better than these now -- maybe refer to them somehow so it\u0027s not maintained twice?","commit_id":"5daf44090947d04c3d330a1aed07cdbf3d57e762"},{"author":{"_account_id":6460,"name":"Brad Topol","email":"btopol@us.ibm.com","username":"btopol"},"change_message_id":"e46de455d4be952ccf5a79dd60c19ebdf25dcad6","unresolved":false,"context_lines":[{"line_number":37,"context_line":"        If success, auth plugin must provide a valid \"user_id\" in"},{"line_number":38,"context_line":"        auth_context. Auth plugin may optionally add any addition methods"},{"line_number":39,"context_line":"        into the \"method_names\""},{"line_number":40,"context_line":"        list. For example, if the authentiation is for rescoping, auth method"},{"line_number":41,"context_line":"        must append the previous method names into \"method_names\". Also, auth"},{"line_number":42,"context_line":"        plugin may add any addition information into the \"extras\" dictionary"},{"line_number":43,"context_line":"        in the auth_context. Anything in \"extras\" will be conveyed in the"}],"source_content_type":"text/x-python","patch_set":6,"id":"AAAAM3%2F%2B6Xc%3D","line":40,"updated":"2013-02-14 18:11:25.000000000","message":"typo:  should be authentication instead of authentiation","commit_id":"5daf44090947d04c3d330a1aed07cdbf3d57e762"},{"author":{"_account_id":6460,"name":"Brad Topol","email":"btopol@us.ibm.com","username":"btopol"},"change_message_id":"e46de455d4be952ccf5a79dd60c19ebdf25dcad6","unresolved":false,"context_lines":[{"line_number":39,"context_line":"        into the \"method_names\""},{"line_number":40,"context_line":"        list. For example, if the authentiation is for rescoping, auth method"},{"line_number":41,"context_line":"        must append the previous method names into \"method_names\". Also, auth"},{"line_number":42,"context_line":"        plugin may add any addition information into the \"extras\" dictionary"},{"line_number":43,"context_line":"        in the auth_context. Anything in \"extras\" will be conveyed in the"},{"line_number":44,"context_line":"        token\u0027s extras field."},{"line_number":45,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"AAAAM3%2F%2B6XI%3D","line":42,"updated":"2013-02-14 18:11:25.000000000","message":"typo: addition should be additional","commit_id":"5daf44090947d04c3d330a1aed07cdbf3d57e762"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"9ce505bf13c6427c10eeebad527910d1bd91e9df","unresolved":false,"context_lines":[{"line_number":43,"context_line":"        in the auth_context. Anything in \"extras\" will be conveyed in the"},{"line_number":44,"context_line":"        token\u0027s extras field."},{"line_number":45,"context_line":""},{"line_number":46,"context_line":"        :returns: None if authenticaiton is successful."},{"line_number":47,"context_line":"                  Authentication payload for the next authentication step if"},{"line_number":48,"context_line":"                  this is a multi-roundtrip authentication."},{"line_number":49,"context_line":"        :raises: exception.Unauthorized for authenticaiton failure."}],"source_content_type":"text/x-python","patch_set":6,"id":"AAAAM3%2F%2B6WI%3D","line":46,"updated":"2013-02-14 18:09:34.000000000","message":"spelling","commit_id":"5daf44090947d04c3d330a1aed07cdbf3d57e762"},{"author":{"_account_id":6460,"name":"Brad Topol","email":"btopol@us.ibm.com","username":"btopol"},"change_message_id":"e46de455d4be952ccf5a79dd60c19ebdf25dcad6","unresolved":false,"context_lines":[{"line_number":43,"context_line":"        in the auth_context. Anything in \"extras\" will be conveyed in the"},{"line_number":44,"context_line":"        token\u0027s extras field."},{"line_number":45,"context_line":""},{"line_number":46,"context_line":"        :returns: None if authenticaiton is successful."},{"line_number":47,"context_line":"                  Authentication payload for the next authentication step if"},{"line_number":48,"context_line":"                  this is a multi-roundtrip authentication."},{"line_number":49,"context_line":"        :raises: exception.Unauthorized for authenticaiton failure."}],"source_content_type":"text/x-python","patch_set":6,"id":"AAAAM3%2F%2B6W4%3D","line":46,"updated":"2013-02-14 18:11:25.000000000","message":"typo authenticaiton should be authentication","commit_id":"5daf44090947d04c3d330a1aed07cdbf3d57e762"},{"author":{"_account_id":6,"name":"Joe Heck","email":"heckj@mac.com","username":"heckj"},"change_message_id":"5b2c6c596329f210a9bc0abf3661cde2f73a7c58","unresolved":false,"context_lines":[{"line_number":34,"context_line":"        :auth_context: user authentication context, a dictionary shared"},{"line_number":35,"context_line":"                       by all plugins. It contains \"method_names\" and \"extras\""},{"line_number":36,"context_line":"                       by default. \"method_names\" is a list and \"extras\" is"},{"line_number":37,"context_line":"                       a dictionary."},{"line_number":38,"context_line":""},{"line_number":39,"context_line":"        If successful, plugin must set \"user_id\" in \"auth_context\"."},{"line_number":40,"context_line":"        \"method_name\" is used to convey any additional authentication methods"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAM3%2F%2B3XM%3D","line":37,"updated":"2013-02-16 01:56:22.000000000","message":"an example dictionary in the docstring would be immensely helpful here","commit_id":"25e13fffbfc512595c1ca19fd378df7d21745056"},{"author":{"_account_id":6,"name":"Joe Heck","email":"heckj@mac.com","username":"heckj"},"change_message_id":"5b2c6c596329f210a9bc0abf3661cde2f73a7c58","unresolved":false,"context_lines":[{"line_number":36,"context_line":"                       by default. \"method_names\" is a list and \"extras\" is"},{"line_number":37,"context_line":"                       a dictionary."},{"line_number":38,"context_line":""},{"line_number":39,"context_line":"        If successful, plugin must set \"user_id\" in \"auth_context\"."},{"line_number":40,"context_line":"        \"method_name\" is used to convey any additional authentication methods"},{"line_number":41,"context_line":"        in case authentication is for re-scoping. For example,"},{"line_number":42,"context_line":"        if the authentication is for re-scoping, plugin must append the"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAM3%2F%2B3XE%3D","line":39,"updated":"2013-02-16 01:56:22.000000000","message":"I think it\u0027s darned awkward to require specific side effects using this as a base handler - the changing of user_id and method_name in an \"auth_context\" dictionary. If we can wrangle it, I\u0027d rather assert that should be returned in the dictionary (with appropriate docstring example) rather than expecting a side effect to happen.","commit_id":"25e13fffbfc512595c1ca19fd378df7d21745056"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"a8b3a625faa7cfcbc18def49ec508c802de1e30e","unresolved":false,"context_lines":[{"line_number":36,"context_line":"                       by default. \"method_names\" is a list and \"extras\" is"},{"line_number":37,"context_line":"                       a dictionary."},{"line_number":38,"context_line":""},{"line_number":39,"context_line":"        If successful, plugin must set \"user_id\" in \"auth_context\"."},{"line_number":40,"context_line":"        \"method_name\" is used to convey any additional authentication methods"},{"line_number":41,"context_line":"        in case authentication is for re-scoping. For example,"},{"line_number":42,"context_line":"        if the authentication is for re-scoping, plugin must append the"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAM3%2F%2B3Qg%3D","line":39,"in_reply_to":"AAAAM3%2F%2B3XE%3D","updated":"2013-02-16 03:00:44.000000000","message":"Yes, the check for \u0027user_id\u0027 is being done in controllers.py.","commit_id":"25e13fffbfc512595c1ca19fd378df7d21745056"}],"keystone/auth/methods/password.py":[{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"5634bd71a9a7c40f1bffc87f7db0b18a1010abf5","unresolved":false,"context_lines":[{"line_number":27,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":28,"context_line":""},{"line_number":29,"context_line":""},{"line_number":30,"context_line":"# (gyee) dependency injection doesn\u0027t seem to work with importutils"},{"line_number":31,"context_line":"# do the explicit import for now."},{"line_number":32,"context_line":"#@dependency.requires(\u0027identity_api\u0027)"},{"line_number":33,"context_line":"class UserAuthInfo(object):"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2FD8s%3D","line":30,"updated":"2013-02-08 14:18:42.000000000","message":"ping me ... i\u0027m curious what the problem is","commit_id":"f03a5dc460399d89064cce9ecf521fad55e26a3a"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"5634bd71a9a7c40f1bffc87f7db0b18a1010abf5","unresolved":false,"context_lines":[{"line_number":70,"context_line":""},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"class Password(auth.AuthMethodHandler):"},{"line_number":73,"context_line":"    def authenticate(self, context, auth_info, user_context):"},{"line_number":74,"context_line":"        \"\"\" Try to authenticate against the identity backend. \"\"\""},{"line_number":75,"context_line":"        user_info \u003d UserAuthInfo(context, auth_info)"},{"line_number":76,"context_line":"        (domain_id, project_id) \u003d auth_info.get_scope()"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2FD6c%3D","line":73,"updated":"2013-02-08 14:18:42.000000000","message":"i\u0027m curious about what the contract is that you expect plugins to fulfill... populate user_context if successful or raise?","commit_id":"f03a5dc460399d89064cce9ecf521fad55e26a3a"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"03e156601c97b1b200e8a6e877079ef97fcb25a8","unresolved":false,"context_lines":[{"line_number":70,"context_line":""},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"class Password(auth.AuthMethodHandler):"},{"line_number":73,"context_line":"    def authenticate(self, context, auth_info, user_context):"},{"line_number":74,"context_line":"        \"\"\" Try to authenticate against the identity backend. \"\"\""},{"line_number":75,"context_line":"        user_info \u003d UserAuthInfo(context, auth_info)"},{"line_number":76,"context_line":"        (domain_id, project_id) \u003d auth_info.get_scope()"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2FDjU%3D","line":73,"in_reply_to":"AAAAM3%2F%2FD6c%3D","updated":"2013-02-08 19:27:44.000000000","message":"I documented it in the abstract class interface.","commit_id":"f03a5dc460399d89064cce9ecf521fad55e26a3a"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"5634bd71a9a7c40f1bffc87f7db0b18a1010abf5","unresolved":false,"context_lines":[{"line_number":76,"context_line":"        (domain_id, project_id) \u003d auth_info.get_scope()"},{"line_number":77,"context_line":""},{"line_number":78,"context_line":"        try:"},{"line_number":79,"context_line":"            # identity.authenticate() can use some refactoring since"},{"line_number":80,"context_line":"            # all we care is password matches"},{"line_number":81,"context_line":"            user_auth_data \u003d self.identity_api.authenticate("},{"line_number":82,"context_line":"                context\u003dcontext,"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2FD6g%3D","line":79,"updated":"2013-02-08 14:18:42.000000000","message":"agree, FIXME?","commit_id":"f03a5dc460399d89064cce9ecf521fad55e26a3a"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"03e156601c97b1b200e8a6e877079ef97fcb25a8","unresolved":false,"context_lines":[{"line_number":76,"context_line":"        (domain_id, project_id) \u003d auth_info.get_scope()"},{"line_number":77,"context_line":""},{"line_number":78,"context_line":"        try:"},{"line_number":79,"context_line":"            # identity.authenticate() can use some refactoring since"},{"line_number":80,"context_line":"            # all we care is password matches"},{"line_number":81,"context_line":"            user_auth_data \u003d self.identity_api.authenticate("},{"line_number":82,"context_line":"                context\u003dcontext,"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2FDjM%3D","line":79,"in_reply_to":"AAAAM3%2F%2FD6g%3D","updated":"2013-02-08 19:27:44.000000000","message":"Will do. :)","commit_id":"f03a5dc460399d89064cce9ecf521fad55e26a3a"},{"author":{"_account_id":2218,"name":"Adam Young","email":"adam@younglogic.com","username":"ayoung"},"change_message_id":"f7c5b5bba57e4077a7700fa85ac89a273661480d","unresolved":false,"context_lines":[{"line_number":51,"context_line":""},{"line_number":52,"context_line":"        # FIXME: identity.authenticate() can use some refactoring since"},{"line_number":53,"context_line":"        # all we care is password matches"},{"line_number":54,"context_line":"        user_auth_data \u003d self.identity_api.authenticate("},{"line_number":55,"context_line":"            context\u003dcontext,"},{"line_number":56,"context_line":"            user_id\u003duser_info.user_id,"},{"line_number":57,"context_line":"            password\u003duser_info.password,"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAM3%2F%2B2Vk%3D","line":54,"updated":"2013-02-17 06:22:28.000000000","message":"Agreed.","commit_id":"25e13fffbfc512595c1ca19fd378df7d21745056"},{"author":{"_account_id":6460,"name":"Brad Topol","email":"btopol@us.ibm.com","username":"btopol"},"change_message_id":"53884e9038c25dfd56d2babd0624a84b7c27d73a","unresolved":false,"context_lines":[{"line_number":44,"context_line":""},{"line_number":45,"context_line":""},{"line_number":46,"context_line":"class Password(auth.AuthMethodHandler):"},{"line_number":47,"context_line":"    def authenticate(self, context, auth_info, user_context):"},{"line_number":48,"context_line":"        \"\"\" Try to authenticate against the identity backend. \"\"\""},{"line_number":49,"context_line":"        user_info \u003d UserAuthInfo(auth_info)"},{"line_number":50,"context_line":"        (domain_id, project_id) \u003d auth_info.get_scope()"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAM3%2F%2BxcE%3D","line":47,"updated":"2013-02-19 15:54:17.000000000","message":"Can you provide more commentary on how this plugin overrides capabilities that were previously found in Driver xxx.\nReally need to make it clear that the plugin is a substitute for previous function that was not as extensible","commit_id":"6c6df626dcc0773c7ae4e8378efdbf8f36763858"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"d5c20ccd065616fdb74bce6665afb523f78e9354","unresolved":false,"context_lines":[{"line_number":44,"context_line":""},{"line_number":45,"context_line":""},{"line_number":46,"context_line":"class Password(auth.AuthMethodHandler):"},{"line_number":47,"context_line":"    def authenticate(self, context, auth_info, user_context):"},{"line_number":48,"context_line":"        \"\"\" Try to authenticate against the identity backend. \"\"\""},{"line_number":49,"context_line":"        user_info \u003d UserAuthInfo(auth_info)"},{"line_number":50,"context_line":"        (domain_id, project_id) \u003d auth_info.get_scope()"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAM3%2F%2BxYw%3D","line":47,"in_reply_to":"AAAAM3%2F%2BxcE%3D","updated":"2013-02-19 16:03:31.000000000","message":"See auth.AuthMethodHandler docstring.","commit_id":"6c6df626dcc0773c7ae4e8378efdbf8f36763858"},{"author":{"_account_id":2218,"name":"Adam Young","email":"adam@younglogic.com","username":"ayoung"},"change_message_id":"33ba53cf7f51f56fa738d0f170490b3ec11f3dfd","unresolved":false,"context_lines":[{"line_number":110,"context_line":"            context\u003dcontext,"},{"line_number":111,"context_line":"            user_id\u003duser_info.user_id,"},{"line_number":112,"context_line":"            password\u003duser_info.password)"},{"line_number":113,"context_line":"        if \u0027user_id\u0027 not in user_context:"},{"line_number":114,"context_line":"            user_context[\u0027user_id\u0027] \u003d user_info.user_id"}],"source_content_type":"text/x-python","patch_set":17,"id":"AAAAM3%2F%2BuwE%3D","line":113,"updated":"2013-02-20 14:59:29.000000000","message":"I would see applying the plug in as a chain of responsibility.  Each plug in should get a definitive swipe at it, and, if it cannot answer a firm \"the user is \u003cusername\u003e\"  it passes it on.  Thus, you shouldn\u0027t be checking to see if the user_id is in the user_context, but rather should be only using the user_id you are passed in the user_info.  If the user_id is in the context already, something should have put it there, and that something should have terminated the chain.","commit_id":"383a77cbdf12c451f1032ecf1f5e8a35b5354847"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"2f5b5e53e68fecfbfcf7df22b798d20fb1c81f14","unresolved":false,"context_lines":[{"line_number":110,"context_line":"            context\u003dcontext,"},{"line_number":111,"context_line":"            user_id\u003duser_info.user_id,"},{"line_number":112,"context_line":"            password\u003duser_info.password)"},{"line_number":113,"context_line":"        if \u0027user_id\u0027 not in user_context:"},{"line_number":114,"context_line":"            user_context[\u0027user_id\u0027] \u003d user_info.user_id"}],"source_content_type":"text/x-python","patch_set":17,"id":"AAAAM3%2F%2Buqw%3D","line":113,"in_reply_to":"AAAAM3%2F%2BuwE%3D","updated":"2013-02-20 16:02:15.000000000","message":"user_id has to come from plugins. There are forms of authentication where the user_id is encrypted/obfuscated and has to be resolved at the plugin level.","commit_id":"383a77cbdf12c451f1032ecf1f5e8a35b5354847"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"cbd0f0238082ef2e249165ca6e41204bf6c355ae","unresolved":false,"context_lines":[{"line_number":111,"context_line":"            user_id\u003duser_info.user_id,"},{"line_number":112,"context_line":"            password\u003duser_info.password)"},{"line_number":113,"context_line":"        if \u0027user_id\u0027 not in user_context:"},{"line_number":114,"context_line":"            user_context[\u0027user_id\u0027] \u003d user_info.user_id"}],"source_content_type":"text/x-python","patch_set":17,"id":"AAAAM3%2F%2Bu2s%3D","line":114,"updated":"2013-02-20 14:00:18.000000000","message":"i still find conditionally modifying the user context to be incredibly confusing. don\u0027t pass in user_context and instead expect the plugin to return a user_id as a string","commit_id":"383a77cbdf12c451f1032ecf1f5e8a35b5354847"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"2f5b5e53e68fecfbfcf7df22b798d20fb1c81f14","unresolved":false,"context_lines":[{"line_number":111,"context_line":"            user_id\u003duser_info.user_id,"},{"line_number":112,"context_line":"            password\u003duser_info.password)"},{"line_number":113,"context_line":"        if \u0027user_id\u0027 not in user_context:"},{"line_number":114,"context_line":"            user_context[\u0027user_id\u0027] \u003d user_info.user_id"}],"source_content_type":"text/x-python","patch_set":17,"id":"AAAAM3%2F%2Buqo%3D","line":114,"in_reply_to":"AAAAM3%2F%2Bu2s%3D","updated":"2013-02-20 16:02:15.000000000","message":"All the plugin\u0027s must agreed on the same user_id or authentication is considered unsuccessful. Besides, auth_context is used to carry other information such as \"extras\" and \"methods\" as well.","commit_id":"383a77cbdf12c451f1032ecf1f5e8a35b5354847"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"f19db779fa3fe9c50abbbb277d75c2b20226df0b","unresolved":false,"context_lines":[{"line_number":111,"context_line":"            user_id\u003duser_info.user_id,"},{"line_number":112,"context_line":"            password\u003duser_info.password)"},{"line_number":113,"context_line":"        if \u0027user_id\u0027 not in user_context:"},{"line_number":114,"context_line":"            user_context[\u0027user_id\u0027] \u003d user_info.user_id"}],"source_content_type":"text/x-python","patch_set":17,"id":"AAAAM3%2F%2BumE%3D","line":114,"in_reply_to":"AAAAM3%2F%2BuoE%3D","updated":"2013-02-20 16:27:43.000000000","message":"user_id has to come from the plugin. As mentioned above, for some forms of authentication, user_id is encrypted/obfuscated and has to resolved at the plugin level.","commit_id":"383a77cbdf12c451f1032ecf1f5e8a35b5354847"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"235b4bc5190e0e9025f0ef096914bfca218821d7","unresolved":false,"context_lines":[{"line_number":111,"context_line":"            user_id\u003duser_info.user_id,"},{"line_number":112,"context_line":"            password\u003duser_info.password)"},{"line_number":113,"context_line":"        if \u0027user_id\u0027 not in user_context:"},{"line_number":114,"context_line":"            user_context[\u0027user_id\u0027] \u003d user_info.user_id"}],"source_content_type":"text/x-python","patch_set":17,"id":"AAAAM3%2F%2BuoE%3D","line":114,"in_reply_to":"AAAAM3%2F%2Buqo%3D","updated":"2013-02-20 16:18:39.000000000","message":"it should be outside of the plugin\u0027s scope of responsibility to enforce that logic","commit_id":"383a77cbdf12c451f1032ecf1f5e8a35b5354847"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"70be2b45b56a2ecaa5cca5d08bd7c146f3d4a220","unresolved":false,"context_lines":[{"line_number":111,"context_line":"            user_id\u003duser_info.user_id,"},{"line_number":112,"context_line":"            password\u003duser_info.password)"},{"line_number":113,"context_line":"        if \u0027user_id\u0027 not in user_context:"},{"line_number":114,"context_line":"            user_context[\u0027user_id\u0027] \u003d user_info.user_id"}],"source_content_type":"text/x-python","patch_set":20,"id":"AAAAM3%2F%2BuT0%3D","line":114,"updated":"2013-02-20 18:13:24.000000000","message":"managing this should be the responsibility of the plugin\u0027s caller, instead:\n\n  return user_info.user_id","commit_id":"466157fb553580f59f15893642bbae573257b7c2"}],"keystone/auth/methods/token.py":[{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"5634bd71a9a7c40f1bffc87f7db0b18a1010abf5","unresolved":false,"context_lines":[{"line_number":19,"context_line":"from keystone import auth"},{"line_number":20,"context_line":"from keystone import token"},{"line_number":21,"context_line":"from keystone.common import dependency"},{"line_number":22,"context_line":"from keystone.common import logging"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"METHOD_NAME \u003d \u0027token\u0027"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2FD8w%3D","line":22,"updated":"2013-02-08 14:18:42.000000000","message":"import order","commit_id":"f03a5dc460399d89064cce9ecf521fad55e26a3a"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"5634bd71a9a7c40f1bffc87f7db0b18a1010abf5","unresolved":false,"context_lines":[{"line_number":29,"context_line":""},{"line_number":30,"context_line":"class Token(auth.AuthMethodHandler):"},{"line_number":31,"context_line":"    def __init__(self):"},{"line_number":32,"context_line":"        self.token_api \u003d token.Manager()"},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"    def authenticate(self, context, auth_info, user_context):"},{"line_number":35,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2FD88%3D","line":32,"updated":"2013-02-08 14:18:42.000000000","message":"@dependency.requires(\u0027token_api\u0027) instead","commit_id":"f03a5dc460399d89064cce9ecf521fad55e26a3a"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"03e156601c97b1b200e8a6e877079ef97fcb25a8","unresolved":false,"context_lines":[{"line_number":29,"context_line":""},{"line_number":30,"context_line":"class Token(auth.AuthMethodHandler):"},{"line_number":31,"context_line":"    def __init__(self):"},{"line_number":32,"context_line":"        self.token_api \u003d token.Manager()"},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"    def authenticate(self, context, auth_info, user_context):"},{"line_number":35,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2FDjI%3D","line":32,"in_reply_to":"AAAAM3%2F%2FD88%3D","updated":"2013-02-08 19:27:44.000000000","message":"I am having trouble with dependency injection. Will need to debug this further.","commit_id":"f03a5dc460399d89064cce9ecf521fad55e26a3a"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"5634bd71a9a7c40f1bffc87f7db0b18a1010abf5","unresolved":false,"context_lines":[{"line_number":46,"context_line":"            user_context[\u0027extras\u0027] +\u003d token_ref[\u0027token_data\u0027][\u0027extras\u0027]"},{"line_number":47,"context_line":"            user_context[\u0027method_names\u0027] +\u003d token_ref[\u0027token_data\u0027][\u0027methods\u0027]"},{"line_number":48,"context_line":"        except AssertionError as e:"},{"line_number":49,"context_line":"            LOG.error(e)"},{"line_number":50,"context_line":"            raise exception.Unauthorized(e)"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2FD80%3D","line":49,"updated":"2013-02-08 14:18:42.000000000","message":"is this really an error? seems like it could just quietly reraise... but i\u0027m also not clear on what would raise an assertion error here","commit_id":"f03a5dc460399d89064cce9ecf521fad55e26a3a"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"03e156601c97b1b200e8a6e877079ef97fcb25a8","unresolved":false,"context_lines":[{"line_number":46,"context_line":"            user_context[\u0027extras\u0027] +\u003d token_ref[\u0027token_data\u0027][\u0027extras\u0027]"},{"line_number":47,"context_line":"            user_context[\u0027method_names\u0027] +\u003d token_ref[\u0027token_data\u0027][\u0027methods\u0027]"},{"line_number":48,"context_line":"        except AssertionError as e:"},{"line_number":49,"context_line":"            LOG.error(e)"},{"line_number":50,"context_line":"            raise exception.Unauthorized(e)"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2FDi8%3D","line":49,"in_reply_to":"AAAAM3%2F%2FD80%3D","updated":"2013-02-08 19:27:44.000000000","message":"Yeah you\u0027re right. I don\u0027t think I need to catch this one.","commit_id":"f03a5dc460399d89064cce9ecf521fad55e26a3a"},{"author":{"_account_id":6460,"name":"Brad Topol","email":"btopol@us.ibm.com","username":"btopol"},"change_message_id":"53884e9038c25dfd56d2babd0624a84b7c27d73a","unresolved":false,"context_lines":[{"line_number":31,"context_line":"    def __init__(self):"},{"line_number":32,"context_line":"        self.token_api \u003d token.Manager()"},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"    def authenticate(self, context, auth_info, user_context):"},{"line_number":35,"context_line":"        try:"},{"line_number":36,"context_line":"            payload \u003d auth_info.get_method_data(METHOD_NAME)"},{"line_number":37,"context_line":"            if \u0027id\u0027 not in payload:"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAM3%2F%2Bxb0%3D","line":34,"updated":"2013-02-19 15:54:17.000000000","message":"Can you provide more commentary on how this plugin overrides capabilities that were previously found in Driver xxx.\nReally need to make it clear that the plugin is a substitute for previous function that was not as extensible","commit_id":"6c6df626dcc0773c7ae4e8378efdbf8f36763858"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"d5c20ccd065616fdb74bce6665afb523f78e9354","unresolved":false,"context_lines":[{"line_number":31,"context_line":"    def __init__(self):"},{"line_number":32,"context_line":"        self.token_api \u003d token.Manager()"},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"    def authenticate(self, context, auth_info, user_context):"},{"line_number":35,"context_line":"        try:"},{"line_number":36,"context_line":"            payload \u003d auth_info.get_method_data(METHOD_NAME)"},{"line_number":37,"context_line":"            if \u0027id\u0027 not in payload:"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAM3%2F%2BxY8%3D","line":34,"in_reply_to":"AAAAM3%2F%2Bxb0%3D","updated":"2013-02-19 16:03:31.000000000","message":"See auth.AuthMethodHandler docstring.","commit_id":"6c6df626dcc0773c7ae4e8378efdbf8f36763858"}],"keystone/auth/routers.py":[{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"5634bd71a9a7c40f1bffc87f7db0b18a1010abf5","unresolved":false,"context_lines":[{"line_number":25,"context_line":"                   controller\u003dauth_controller,"},{"line_number":26,"context_line":"                   action\u003d\u0027authenticate_for_token\u0027,"},{"line_number":27,"context_line":"                   conditions\u003ddict(method\u003d[\u0027POST\u0027]))"},{"line_number":28,"context_line":"    mapper.connect(\u0027/tokens\u0027,"},{"line_number":29,"context_line":"                   controller\u003dauth_controller,"},{"line_number":30,"context_line":"                   action\u003d\u0027check_token\u0027,"},{"line_number":31,"context_line":"                   conditions\u003ddict(method\u003d[\u0027HEAD\u0027]))"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2FD9A%3D","line":28,"updated":"2013-02-08 14:18:42.000000000","message":"i thought these were going to be on /auth/ or /auth/tokens or something","commit_id":"f03a5dc460399d89064cce9ecf521fad55e26a3a"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"03e156601c97b1b200e8a6e877079ef97fcb25a8","unresolved":false,"context_lines":[{"line_number":25,"context_line":"                   controller\u003dauth_controller,"},{"line_number":26,"context_line":"                   action\u003d\u0027authenticate_for_token\u0027,"},{"line_number":27,"context_line":"                   conditions\u003ddict(method\u003d[\u0027POST\u0027]))"},{"line_number":28,"context_line":"    mapper.connect(\u0027/tokens\u0027,"},{"line_number":29,"context_line":"                   controller\u003dauth_controller,"},{"line_number":30,"context_line":"                   action\u003d\u0027check_token\u0027,"},{"line_number":31,"context_line":"                   conditions\u003ddict(method\u003d[\u0027HEAD\u0027]))"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2FDis%3D","line":28,"in_reply_to":"AAAAM3%2F%2FD9A%3D","updated":"2013-02-08 19:27:44.000000000","message":"My understanding is that only the authentication part goes to /auth/tokens, the rest are still parked under /tokens. Do I need to update the spec?","commit_id":"f03a5dc460399d89064cce9ecf521fad55e26a3a"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"5634bd71a9a7c40f1bffc87f7db0b18a1010abf5","unresolved":false,"context_lines":[{"line_number":31,"context_line":"                   conditions\u003ddict(method\u003d[\u0027HEAD\u0027]))"},{"line_number":32,"context_line":"    mapper.connect(\u0027/tokens\u0027,"},{"line_number":33,"context_line":"                   controller\u003dauth_controller,"},{"line_number":34,"context_line":"                   action\u003d\u0027delete_token\u0027,"},{"line_number":35,"context_line":"                   conditions\u003ddict(method\u003d[\u0027DELETE\u0027]))"},{"line_number":36,"context_line":"    mapper.connect(\u0027/tokens\u0027,"},{"line_number":37,"context_line":"                   controller\u003dauth_controller,"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2FD9I%3D","line":34,"updated":"2013-02-08 14:18:42.000000000","message":"revoke_token?","commit_id":"f03a5dc460399d89064cce9ecf521fad55e26a3a"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"03e156601c97b1b200e8a6e877079ef97fcb25a8","unresolved":false,"context_lines":[{"line_number":31,"context_line":"                   conditions\u003ddict(method\u003d[\u0027HEAD\u0027]))"},{"line_number":32,"context_line":"    mapper.connect(\u0027/tokens\u0027,"},{"line_number":33,"context_line":"                   controller\u003dauth_controller,"},{"line_number":34,"context_line":"                   action\u003d\u0027delete_token\u0027,"},{"line_number":35,"context_line":"                   conditions\u003ddict(method\u003d[\u0027DELETE\u0027]))"},{"line_number":36,"context_line":"    mapper.connect(\u0027/tokens\u0027,"},{"line_number":37,"context_line":"                   controller\u003dauth_controller,"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2FDi4%3D","line":34,"in_reply_to":"AAAAM3%2F%2FD9I%3D","updated":"2013-02-08 19:27:44.000000000","message":"Good catch!","commit_id":"f03a5dc460399d89064cce9ecf521fad55e26a3a"},{"author":{"_account_id":2218,"name":"Adam Young","email":"adam@younglogic.com","username":"ayoung"},"change_message_id":"f7c5b5bba57e4077a7700fa85ac89a273661480d","unresolved":false,"context_lines":[{"line_number":21,"context_line":"def append_v3_routers(mapper, routers):"},{"line_number":22,"context_line":"    auth_controller \u003d controllers.Auth()"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"    mapper.connect(\u0027/auth\u0027,"},{"line_number":25,"context_line":"                   controller\u003dauth_controller,"},{"line_number":26,"context_line":"                   action\u003d\u0027authenticate_for_token\u0027,"},{"line_number":27,"context_line":"                   conditions\u003ddict(method\u003d[\u0027POST\u0027]))"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAM3%2F%2B2Vg%3D","line":24,"updated":"2013-02-17 06:22:28.000000000","message":"/auth/token","commit_id":"25e13fffbfc512595c1ca19fd378df7d21745056"},{"author":{"_account_id":2218,"name":"Adam Young","email":"adam@younglogic.com","username":"ayoung"},"change_message_id":"33d973d9bdaa3daa15a4f286376db2ffc3f3d828","unresolved":false,"context_lines":[{"line_number":21,"context_line":"def append_v3_routers(mapper, routers):"},{"line_number":22,"context_line":"    auth_controller \u003d controllers.Auth()"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"    mapper.connect(\u0027/auth\u0027,"},{"line_number":25,"context_line":"                   controller\u003dauth_controller,"},{"line_number":26,"context_line":"                   action\u003d\u0027authenticate_for_token\u0027,"},{"line_number":27,"context_line":"                   conditions\u003ddict(method\u003d[\u0027POST\u0027]))"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAM3%2F%2BynA%3D","line":24,"updated":"2013-02-19 05:50:37.000000000","message":"Need to make this /auth/tokens or you are going to make it impossible to handle non-token auth.  Or, change this to token, I am ok with that as well.","commit_id":"6c6df626dcc0773c7ae4e8378efdbf8f36763858"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"d5c20ccd065616fdb74bce6665afb523f78e9354","unresolved":false,"context_lines":[{"line_number":21,"context_line":"def append_v3_routers(mapper, routers):"},{"line_number":22,"context_line":"    auth_controller \u003d controllers.Auth()"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"    mapper.connect(\u0027/auth\u0027,"},{"line_number":25,"context_line":"                   controller\u003dauth_controller,"},{"line_number":26,"context_line":"                   action\u003d\u0027authenticate_for_token\u0027,"},{"line_number":27,"context_line":"                   conditions\u003ddict(method\u003d[\u0027POST\u0027]))"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAM3%2F%2BxcU%3D","line":24,"in_reply_to":"AAAAM3%2F%2BynA%3D","updated":"2013-02-19 16:03:31.000000000","message":"I am fine with making it /auth/tokens once the new spec is approved. Don\u0027t want to keep changing it till the spec is settle.","commit_id":"6c6df626dcc0773c7ae4e8378efdbf8f36763858"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"831770108aa1ea9f00eddbec0d6ab2b99f1743b7","unresolved":false,"context_lines":[{"line_number":37,"context_line":"                   controller\u003dauth_controller,"},{"line_number":38,"context_line":"                   action\u003d\u0027validate_token\u0027,"},{"line_number":39,"context_line":"                   conditions\u003ddict(method\u003d[\u0027GET\u0027]))"},{"line_number":40,"context_line":"    mapper.connect(\u0027/auth/tokens/revoked\u0027,"},{"line_number":41,"context_line":"                   controller\u003dauth_controller,"},{"line_number":42,"context_line":"                   action\u003d\u0027revocation_list\u0027,"},{"line_number":43,"context_line":"                   conditions\u003ddict(method\u003d[\u0027GET\u0027]))"}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAAM3%2F%2BwzU%3D","line":40,"updated":"2013-02-19 19:22:18.000000000","message":"undocumented API?","commit_id":"cd4967b4e562bf0f604ac1cb8fa8e91ebf535682"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"7f2a7e912ea3e47e7c02c470e6128f2e88aba08f","unresolved":false,"context_lines":[{"line_number":40,"context_line":"    mapper.connect(\u0027/auth/tokens/OS-PKI/revoked\u0027,"},{"line_number":41,"context_line":"                   controller\u003dauth_controller,"},{"line_number":42,"context_line":"                   action\u003d\u0027revocation_list\u0027,"},{"line_number":43,"context_line":"                   conditions\u003ddict(method\u003d[\u0027GET\u0027]))"}],"source_content_type":"text/x-python","patch_set":24,"id":"AAAATn%2F%2F0HQ%3D","line":43,"updated":"2013-10-28 15:48:56.000000000","message":"this change introduced undocumented API\u0027s","commit_id":"9f812939d4b05384b0a7d48e6b916baeca0477dc"}],"keystone/auth/token_factory.py":[{"author":{"_account_id":2218,"name":"Adam Young","email":"adam@younglogic.com","username":"ayoung"},"change_message_id":"f7c5b5bba57e4077a7700fa85ac89a273661480d","unresolved":false,"context_lines":[{"line_number":82,"context_line":"                                                               domain_id,"},{"line_number":83,"context_line":"                                                               project_id)"},{"line_number":84,"context_line":"        # (gyee): no idea wtf\u0027s roles_links. setting it because its in the spec"},{"line_number":85,"context_line":"        token_data[\u0027user\u0027][\u0027roles_links\u0027] \u003d []"},{"line_number":86,"context_line":""},{"line_number":87,"context_line":"    def _populate_service_catalog(self, token_data, user_id,"},{"line_number":88,"context_line":"                                  domain_id, project_id):"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAM3%2F%2B2VE%3D","line":85,"updated":"2013-02-17 06:22:28.000000000","message":"the hyperlinks to the actual role objects, HATEOAS.","commit_id":"25e13fffbfc512595c1ca19fd378df7d21745056"},{"author":{"_account_id":6,"name":"Joe Heck","email":"heckj@mac.com","username":"heckj"},"change_message_id":"5b2c6c596329f210a9bc0abf3661cde2f73a7c58","unresolved":false,"context_lines":[{"line_number":165,"context_line":"                \u0027expires\u0027: expiry,"},{"line_number":166,"context_line":"                \u0027token_data\u0027: token_data}"},{"line_number":167,"context_line":"        token_api.create_token(context, token_id, data)"},{"line_number":168,"context_line":"    except Exception as e:"},{"line_number":169,"context_line":"        # an identical token may have been created already."},{"line_number":170,"context_line":"        # if so, return the token_data as it is also identical"},{"line_number":171,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAM3%2F%2B3XA%3D","line":168,"updated":"2013-02-16 01:56:22.000000000","message":"this is a very, very broad exception to catch here - can it be narrowed?","commit_id":"25e13fffbfc512595c1ca19fd378df7d21745056"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"6b23656acdb4929dce4bb630b879f3bc597b3c06","unresolved":false,"context_lines":[{"line_number":103,"context_line":"        # we only care about id and name"},{"line_number":104,"context_line":"        filtered_role \u003d []"},{"line_number":105,"context_line":"        for role in roles:"},{"line_number":106,"context_line":"            filtered_role.append({\u0027id\u0027: role[\u0027id\u0027], \u0027name\u0027: role[\u0027name\u0027]})"},{"line_number":107,"context_line":"        token_data[\u0027roles\u0027] \u003d roles"},{"line_number":108,"context_line":""},{"line_number":109,"context_line":"    def _populate_service_catalog(self, token_data, user_id,"}],"source_content_type":"text/x-python","patch_set":19,"id":"AAAAM3%2F%2BuV4%3D","line":106,"updated":"2013-02-20 17:58:59.000000000","message":"you\u0027re not doing anything with filtered_roles here","commit_id":"54a95902e2348c56ba85a9070a605a8681996226"}],"keystone/catalog/backends/sql.py":[{"author":{"_account_id":6460,"name":"Brad Topol","email":"btopol@us.ibm.com","username":"btopol"},"change_message_id":"e46de455d4be952ccf5a79dd60c19ebdf25dcad6","unresolved":false,"context_lines":[{"line_number":173,"context_line":""},{"line_number":174,"context_line":"        return catalog"},{"line_number":175,"context_line":""},{"line_number":176,"context_line":"    def get_v3_catalog(self, user_id, tenant_id, metadata\u003dNone):"},{"line_number":177,"context_line":"        d \u003d dict(CONF.iteritems())"},{"line_number":178,"context_line":"        d.update({\u0027tenant_id\u0027: tenant_id,"},{"line_number":179,"context_line":"                  \u0027user_id\u0027: user_id})"}],"source_content_type":"text/x-python","patch_set":6,"id":"AAAAM3%2F%2B6ko%3D","line":176,"updated":"2013-02-14 18:11:25.000000000","message":"I don\u0027t understand why the catalog enhancements were needed to support pluggable authentication","commit_id":"5daf44090947d04c3d330a1aed07cdbf3d57e762"}],"keystone/catalog/core.py":[{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"5634bd71a9a7c40f1bffc87f7db0b18a1010abf5","unresolved":false,"context_lines":[{"line_number":225,"context_line":"                    {"},{"line_number":226,"context_line":"                        \"interface\": \"public\","},{"line_number":227,"context_line":"                        \"id\": \"--endpoint-id--\","},{"line_number":228,"context_line":"                        \"name\": null,"},{"line_number":229,"context_line":"                        \"region\": \"RegionOne\","},{"line_number":230,"context_line":"                        \"url\": \"http://external:8776/v1/--project-id--\""},{"line_number":231,"context_line":"                    },"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2FD9M%3D","line":228,"updated":"2013-02-08 14:18:42.000000000","message":"what\u0027s an endpoint name?","commit_id":"f03a5dc460399d89064cce9ecf521fad55e26a3a"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"03e156601c97b1b200e8a6e877079ef97fcb25a8","unresolved":false,"context_lines":[{"line_number":225,"context_line":"                    {"},{"line_number":226,"context_line":"                        \"interface\": \"public\","},{"line_number":227,"context_line":"                        \"id\": \"--endpoint-id--\","},{"line_number":228,"context_line":"                        \"name\": null,"},{"line_number":229,"context_line":"                        \"region\": \"RegionOne\","},{"line_number":230,"context_line":"                        \"url\": \"http://external:8776/v1/--project-id--\""},{"line_number":231,"context_line":"                    },"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2FDiQ%3D","line":228,"in_reply_to":"AAAAM3%2F%2FD9M%3D","updated":"2013-02-08 19:27:44.000000000","message":"Don\u0027t remember adding this code. Could\u0027ve been from a bad rebase. I\u0027ll double check.","commit_id":"f03a5dc460399d89064cce9ecf521fad55e26a3a"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"0cc06797a3047b1f3e48cbeb7b3faf0c09fd22af","unresolved":false,"context_lines":[{"line_number":235,"context_line":"                        \"url\": \"http://internal:8776/v1/--project-id--\""},{"line_number":236,"context_line":"                    }],"},{"line_number":237,"context_line":"                \"id\": \"--service-id--\","},{"line_number":238,"context_line":"                \"type\": \"volume\""},{"line_number":239,"context_line":"            }]"},{"line_number":240,"context_line":""},{"line_number":241,"context_line":"        :returns: A list representing the service catalog or an empty list"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAAM3%2F%2B%2B60%3D","line":238,"updated":"2013-02-12 15:42:20.000000000","message":"indentation here seems to be messed up","commit_id":"026f19ee81eeb09f1aba9c287189495627e833aa"},{"author":{"_account_id":6460,"name":"Brad Topol","email":"btopol@us.ibm.com","username":"btopol"},"change_message_id":"e46de455d4be952ccf5a79dd60c19ebdf25dcad6","unresolved":false,"context_lines":[{"line_number":214,"context_line":"        \"\"\""},{"line_number":215,"context_line":"        raise exception.NotImplemented()"},{"line_number":216,"context_line":""},{"line_number":217,"context_line":"    def get_v3_catalog(self, user_id, tenant_id, metadata\u003dNone):"},{"line_number":218,"context_line":"        \"\"\"Retrieve and format the current V3 service catalog."},{"line_number":219,"context_line":""},{"line_number":220,"context_line":"        Example::"}],"source_content_type":"text/x-python","patch_set":6,"id":"AAAAM3%2F%2B6k8%3D","line":217,"updated":"2013-02-14 18:11:25.000000000","message":"why did you need to add this to support your pluggable authentication work?","commit_id":"5daf44090947d04c3d330a1aed07cdbf3d57e762"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"232ec87e1195fb33566c0e7a0bf6603cb09e637b","unresolved":false,"context_lines":[{"line_number":214,"context_line":"        \"\"\""},{"line_number":215,"context_line":"        raise exception.NotImplemented()"},{"line_number":216,"context_line":""},{"line_number":217,"context_line":"    def get_v3_catalog(self, user_id, tenant_id, metadata\u003dNone):"},{"line_number":218,"context_line":"        \"\"\"Retrieve and format the current V3 service catalog."},{"line_number":219,"context_line":""},{"line_number":220,"context_line":"        Example::"}],"source_content_type":"text/x-python","patch_set":6,"id":"AAAAM3%2F%2B6SQ%3D","line":217,"in_reply_to":"AAAAM3%2F%2B6k8%3D","updated":"2013-02-14 18:23:42.000000000","message":"this change is tackling several blueprints at once, which all go hand in hand... this is a little more closely related to blueprint stop-ids-in-uris, which is effectively \"implement Identity API v3 authentication\", which includes a rewrite of the service catalog design\n\ngyee is brave.","commit_id":"5daf44090947d04c3d330a1aed07cdbf3d57e762"},{"author":{"_account_id":6,"name":"Joe Heck","email":"heckj@mac.com","username":"heckj"},"change_message_id":"5b2c6c596329f210a9bc0abf3661cde2f73a7c58","unresolved":false,"context_lines":[{"line_number":214,"context_line":"        \"\"\""},{"line_number":215,"context_line":"        raise exception.NotImplemented()"},{"line_number":216,"context_line":""},{"line_number":217,"context_line":"    def get_v3_catalog(self, user_id, tenant_id, metadata\u003dNone):"},{"line_number":218,"context_line":"        \"\"\"Retrieve and format the current V3 service catalog."},{"line_number":219,"context_line":""},{"line_number":220,"context_line":"        Example::"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAM3%2F%2B3W8%3D","line":217,"updated":"2013-02-16 01:56:22.000000000","message":"why are we adding a version specific method here instead of over-ridding the existing get_catalog in the appropriate versioned handler/subclass?\n\nReally don\u0027t want to add version specific methods","commit_id":"25e13fffbfc512595c1ca19fd378df7d21745056"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"a8b3a625faa7cfcbc18def49ec508c802de1e30e","unresolved":false,"context_lines":[{"line_number":214,"context_line":"        \"\"\""},{"line_number":215,"context_line":"        raise exception.NotImplemented()"},{"line_number":216,"context_line":""},{"line_number":217,"context_line":"    def get_v3_catalog(self, user_id, tenant_id, metadata\u003dNone):"},{"line_number":218,"context_line":"        \"\"\"Retrieve and format the current V3 service catalog."},{"line_number":219,"context_line":""},{"line_number":220,"context_line":"        Example::"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAM3%2F%2B3RA%3D","line":217,"in_reply_to":"AAAAM3%2F%2B3W8%3D","updated":"2013-02-16 03:00:44.000000000","message":"We have to support both v2 and v3 at the same time. I can\u0027t think of a good way to over-ride this interface. But yes, its rather ugly right now.","commit_id":"25e13fffbfc512595c1ca19fd378df7d21745056"}],"keystone/common/wsgi.py":[{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"5634bd71a9a7c40f1bffc87f7db0b18a1010abf5","unresolved":false,"context_lines":[{"line_number":233,"context_line":"        except (exception.AuthMethodNotSupported,"},{"line_number":234,"context_line":"                exception.AdditionalAuthRequired) as e:"},{"line_number":235,"context_line":"            LOG.warning(e)"},{"line_number":236,"context_line":"            return render_auth_exception(e)"},{"line_number":237,"context_line":"        except exception.Error as e:"},{"line_number":238,"context_line":"            LOG.warning(e)"},{"line_number":239,"context_line":"            return render_exception(e)"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2FD9k%3D","line":236,"updated":"2013-02-08 14:18:42.000000000","message":"not sure this is valuable if these two exceptions extend exception.Unauthorized which is handled above","commit_id":"f03a5dc460399d89064cce9ecf521fad55e26a3a"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"5634bd71a9a7c40f1bffc87f7db0b18a1010abf5","unresolved":false,"context_lines":[{"line_number":558,"context_line":"            \u0027message\u0027: str(error),"},{"line_number":559,"context_line":"        },"},{"line_number":560,"context_line":"        \u0027authentication\u0027: error.authentication"},{"line_number":561,"context_line":"    })"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2FD9U%3D","line":561,"updated":"2013-02-08 14:18:42.000000000","message":"share code with render_exception as much as possible... i\u0027d kinda rather see a `if isinstance(error, Unauthorized): append \u0027authentication\u0027...` instead","commit_id":"f03a5dc460399d89064cce9ecf521fad55e26a3a"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"03e156601c97b1b200e8a6e877079ef97fcb25a8","unresolved":false,"context_lines":[{"line_number":558,"context_line":"            \u0027message\u0027: str(error),"},{"line_number":559,"context_line":"        },"},{"line_number":560,"context_line":"        \u0027authentication\u0027: error.authentication"},{"line_number":561,"context_line":"    })"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2FDiM%3D","line":561,"in_reply_to":"AAAAM3%2F%2FD9U%3D","updated":"2013-02-08 19:27:44.000000000","message":"Make sense.","commit_id":"f03a5dc460399d89064cce9ecf521fad55e26a3a"},{"author":{"_account_id":2340,"name":"Ionut Artarisi","email":"iartarisi@suse.cz","username":"mapleoin"},"change_message_id":"8347ee1f0a4068c5f74d51bb197ff5be4daafeb4","unresolved":false,"context_lines":[{"line_number":540,"context_line":""},{"line_number":541,"context_line":"def render_exception(error):"},{"line_number":542,"context_line":"    \"\"\"Forms a WSGI response based on the current error.\"\"\""},{"line_number":543,"context_line":"    is_auth_exception \u003d (isinstance(error, exception.AdditionalAuthRequired) or"},{"line_number":544,"context_line":"                         isinstance(error, exception.AuthMethodNotSupported))"},{"line_number":545,"context_line":"    if is_auth_exception:"},{"line_number":546,"context_line":"        return render_response(status\u003d(error.code, error.title), body\u003d{"}],"source_content_type":"text/x-python","patch_set":6,"id":"AAAAM3%2F%2B7EM%3D","line":543,"updated":"2013-02-14 10:52:12.000000000","message":"This hardcodes classes when it\u0027s not really necessary. It looks like just checking the error\u0027s interface for the presence of the authentication attr would be easier. You could do that in a try: body.update(authentication\u003derror.authentication) except AttributeError: pass block. And then have only one return and no isinstance calls.","commit_id":"5daf44090947d04c3d330a1aed07cdbf3d57e762"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"9ce505bf13c6427c10eeebad527910d1bd91e9df","unresolved":false,"context_lines":[{"line_number":540,"context_line":""},{"line_number":541,"context_line":"def render_exception(error):"},{"line_number":542,"context_line":"    \"\"\"Forms a WSGI response based on the current error.\"\"\""},{"line_number":543,"context_line":"    is_auth_exception \u003d (isinstance(error, exception.AdditionalAuthRequired) or"},{"line_number":544,"context_line":"                         isinstance(error, exception.AuthMethodNotSupported))"},{"line_number":545,"context_line":"    if is_auth_exception:"},{"line_number":546,"context_line":"        return render_response(status\u003d(error.code, error.title), body\u003d{"}],"source_content_type":"text/x-python","patch_set":6,"id":"AAAAM3%2F%2B6Vw%3D","line":543,"in_reply_to":"AAAAM3%2F%2B6mw%3D","updated":"2013-02-14 18:09:34.000000000","message":"(as mentioned on previous patches) that\u0027s why you should have these both extend a base class that guarantees an interface, and then only check for that here","commit_id":"5daf44090947d04c3d330a1aed07cdbf3d57e762"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"3bc73a95406fa4c47efa37a227d7155c196c817f","unresolved":false,"context_lines":[{"line_number":540,"context_line":""},{"line_number":541,"context_line":"def render_exception(error):"},{"line_number":542,"context_line":"    \"\"\"Forms a WSGI response based on the current error.\"\"\""},{"line_number":543,"context_line":"    is_auth_exception \u003d (isinstance(error, exception.AdditionalAuthRequired) or"},{"line_number":544,"context_line":"                         isinstance(error, exception.AuthMethodNotSupported))"},{"line_number":545,"context_line":"    if is_auth_exception:"},{"line_number":546,"context_line":"        return render_response(status\u003d(error.code, error.title), body\u003d{"}],"source_content_type":"text/x-python","patch_set":6,"id":"AAAAM3%2F%2B6mw%3D","line":543,"in_reply_to":"AAAAM3%2F%2B7EM%3D","updated":"2013-02-14 16:46:42.000000000","message":"I thought about your approach as well when I started implemented the response. One problem I see is that the attribute \"authentication\" may not be consistently use. Say there\u0027s another exception comes along and extends Unauthroized and happened to its own \"authentication\" attribute but used for a different purposed. Therefore, I want it to be very specific.","commit_id":"5daf44090947d04c3d330a1aed07cdbf3d57e762"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"9ce505bf13c6427c10eeebad527910d1bd91e9df","unresolved":false,"context_lines":[{"line_number":556,"context_line":"            \u0027error\u0027: {"},{"line_number":557,"context_line":"                \u0027code\u0027: error.code,"},{"line_number":558,"context_line":"                \u0027title\u0027: error.title,"},{"line_number":559,"context_line":"                \u0027message\u0027: str(error),"},{"line_number":560,"context_line":"            }"},{"line_number":561,"context_line":"        })"}],"source_content_type":"text/x-python","patch_set":6,"id":"AAAAM3%2F%2B6Vo%3D","line":559,"updated":"2013-02-14 18:09:34.000000000","message":"don\u0027t build the response twice, build it once and modify it as appropriate -- this is still twice the maintenance effort ;)","commit_id":"5daf44090947d04c3d330a1aed07cdbf3d57e762"}],"keystone/config.py":[{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"5634bd71a9a7c40f1bffc87f7db0b18a1010abf5","unresolved":false,"context_lines":[{"line_number":258,"context_line":"register_str(\u0027driver\u0027, group\u003d\u0027password_method\u0027,"},{"line_number":259,"context_line":"             default\u003d\u0027keystone.auth.methods.password\u0027)"},{"line_number":260,"context_line":"register_str(\u0027driver\u0027, group\u003d\u0027token_method\u0027,"},{"line_number":261,"context_line":"             default\u003d\u0027keystone.auth.methods.token\u0027)"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2FD%2BE%3D","line":261,"updated":"2013-02-08 14:18:42.000000000","message":"should these last two groups be registered dynamically? (ideally)","commit_id":"f03a5dc460399d89064cce9ecf521fad55e26a3a"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"03e156601c97b1b200e8a6e877079ef97fcb25a8","unresolved":false,"context_lines":[{"line_number":258,"context_line":"register_str(\u0027driver\u0027, group\u003d\u0027password_method\u0027,"},{"line_number":259,"context_line":"             default\u003d\u0027keystone.auth.methods.password\u0027)"},{"line_number":260,"context_line":"register_str(\u0027driver\u0027, group\u003d\u0027token_method\u0027,"},{"line_number":261,"context_line":"             default\u003d\u0027keystone.auth.methods.token\u0027)"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2FDhw%3D","line":261,"in_reply_to":"AAAAM3%2F%2FD%2BE%3D","updated":"2013-02-08 19:27:44.000000000","message":"Sounds good.","commit_id":"f03a5dc460399d89064cce9ecf521fad55e26a3a"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"0cc06797a3047b1f3e48cbeb7b3faf0c09fd22af","unresolved":false,"context_lines":[{"line_number":290,"context_line":"register_str(\u0027userid\u0027, group\u003d\u0027pam\u0027, default\u003dNone)"},{"line_number":291,"context_line":"register_str(\u0027password\u0027, group\u003d\u0027pam\u0027, default\u003dNone)"},{"line_number":292,"context_line":""},{"line_number":293,"context_line":"#authn_handlers"},{"line_number":294,"context_line":"register_list(\u0027methods\u0027, group\u003d\u0027auth\u0027,"},{"line_number":295,"context_line":"              default\u003d[\u0027password\u0027, \u0027token\u0027])"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAAM3%2F%2B%2B5s%3D","line":293,"updated":"2013-02-12 15:42:20.000000000","message":"no need for abbreviations here:\n\n  # authentication handlers\n\nalso include a space after the hash","commit_id":"026f19ee81eeb09f1aba9c287189495627e833aa"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"0cc06797a3047b1f3e48cbeb7b3faf0c09fd22af","unresolved":false,"context_lines":[{"line_number":292,"context_line":""},{"line_number":293,"context_line":"#authn_handlers"},{"line_number":294,"context_line":"register_list(\u0027methods\u0027, group\u003d\u0027auth\u0027,"},{"line_number":295,"context_line":"              default\u003d[\u0027password\u0027, \u0027token\u0027])"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAAM3%2F%2B%2B5o%3D","line":295,"updated":"2013-02-12 15:42:20.000000000","message":"you also need to register default authentication plugins here","commit_id":"026f19ee81eeb09f1aba9c287189495627e833aa"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"b8598ae0105d169d6a43f02885c85552521f7784","unresolved":false,"context_lines":[{"line_number":312,"context_line":"register_str(\u0027password\u0027, group\u003d\u0027auth\u0027,"},{"line_number":313,"context_line":"             default\u003d\u0027keystone.auth.methods.token.Token\u0027)"},{"line_number":314,"context_line":"register_str(\u0027token\u0027, group\u003d\u0027auth\u0027,"},{"line_number":315,"context_line":"             default\u003d\u0027keystone.auth.methods.password.Password\u0027)"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAM3%2F%2Bw8E%3D","line":315,"updated":"2013-02-19 18:20:54.000000000","message":"from a mailing list discussion... how impactful would it be to change these two register_str to register_list, and then iterate through the defined drivers until a driver authenticates successfully or they all fail? in the base case we would only have 1 driver\n\nthe goal being to allow deployments to use our builtin password auth, but then write their own password driver that keystone should fall back on if, say, keystone isn\u0027t already aware of a user from an external system","commit_id":"6c6df626dcc0773c7ae4e8378efdbf8f36763858"}],"keystone/exception.py":[{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"5634bd71a9a7c40f1bffc87f7db0b18a1010abf5","unresolved":false,"context_lines":[{"line_number":114,"context_line":"    title \u003d \u0027Not Authorized\u0027"},{"line_number":115,"context_line":""},{"line_number":116,"context_line":""},{"line_number":117,"context_line":"class AuthMethodNotSupported(SecurityError):"},{"line_number":118,"context_line":"    \"\"\" Need to authenticate with one or more supported methods. \"\"\""},{"line_number":119,"context_line":"    code \u003d 401"},{"line_number":120,"context_line":"    title \u003d \u0027Not Authorized\u0027"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2FD%2BA%3D","line":117,"updated":"2013-02-08 14:18:42.000000000","message":"These can/should extend Unauthorized... and you\u0027ll get the code \u0026 title for free","commit_id":"f03a5dc460399d89064cce9ecf521fad55e26a3a"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"5634bd71a9a7c40f1bffc87f7db0b18a1010abf5","unresolved":false,"context_lines":[{"line_number":115,"context_line":""},{"line_number":116,"context_line":""},{"line_number":117,"context_line":"class AuthMethodNotSupported(SecurityError):"},{"line_number":118,"context_line":"    \"\"\" Need to authenticate with one or more supported methods. \"\"\""},{"line_number":119,"context_line":"    code \u003d 401"},{"line_number":120,"context_line":"    title \u003d \u0027Not Authorized\u0027"},{"line_number":121,"context_line":"    authentication \u003d {\u0027methods\u0027: CONF.auth.methods}"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2FD94%3D","line":118,"updated":"2013-02-08 14:18:42.000000000","message":"I feel like the message could better reflect the fact that the attempted authorization method was not supported","commit_id":"f03a5dc460399d89064cce9ecf521fad55e26a3a"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"5634bd71a9a7c40f1bffc87f7db0b18a1010abf5","unresolved":false,"context_lines":[{"line_number":127,"context_line":"    title \u003d \u0027Not Authorized\u0027"},{"line_number":128,"context_line":""},{"line_number":129,"context_line":"    def __init__(self, auth_response):"},{"line_number":130,"context_line":"        self.authentication \u003d auth_response"},{"line_number":131,"context_line":""},{"line_number":132,"context_line":""},{"line_number":133,"context_line":"class Forbidden(SecurityError):"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2FD98%3D","line":130,"updated":"2013-02-08 14:18:42.000000000","message":"!!! don\u0027t override __init__ without at least calling super(), this exception is probably unrenderable","commit_id":"f03a5dc460399d89064cce9ecf521fad55e26a3a"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"03e156601c97b1b200e8a6e877079ef97fcb25a8","unresolved":false,"context_lines":[{"line_number":127,"context_line":"    title \u003d \u0027Not Authorized\u0027"},{"line_number":128,"context_line":""},{"line_number":129,"context_line":"    def __init__(self, auth_response):"},{"line_number":130,"context_line":"        self.authentication \u003d auth_response"},{"line_number":131,"context_line":""},{"line_number":132,"context_line":""},{"line_number":133,"context_line":"class Forbidden(SecurityError):"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2FDho%3D","line":130,"in_reply_to":"AAAAM3%2F%2FD98%3D","updated":"2013-02-08 19:27:44.000000000","message":"Good catch!","commit_id":"f03a5dc460399d89064cce9ecf521fad55e26a3a"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"0cc06797a3047b1f3e48cbeb7b3faf0c09fd22af","unresolved":false,"context_lines":[{"line_number":114,"context_line":"    title \u003d \u0027Not Authorized\u0027"},{"line_number":115,"context_line":""},{"line_number":116,"context_line":""},{"line_number":117,"context_line":"class AuthMethodNotSupported(Unauthorized):"},{"line_number":118,"context_line":"    \"\"\" Attempted to authenticate with an unsupported method. \"\"\""},{"line_number":119,"context_line":"    authentication \u003d {\u0027methods\u0027: CONF.auth.methods}"},{"line_number":120,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAAM3%2F%2B%2B6o%3D","line":117,"updated":"2013-02-12 15:42:20.000000000","message":"if both of these new classes extended an intermediary object, like\n\n  class AuthenticationMethodError(Unauthorized):\n      \"\"\"Authentication method failed.\"\"\"\n      authentication \u003d {}\n\nthen you\u0027d have a common object that was expected to have an authentication attribute, and one class to check for isinstance(error, AuthenticationMethodError) in render_exception -- it\u0027d also give proprietary authentication methods a common exception to extend","commit_id":"026f19ee81eeb09f1aba9c287189495627e833aa"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"9ce505bf13c6427c10eeebad527910d1bd91e9df","unresolved":false,"context_lines":[{"line_number":124,"context_line":""},{"line_number":125,"context_line":"    def __init__(self, auth_response\u003dNone, **kwargs):"},{"line_number":126,"context_line":"        super(AdditionalAuthRequired, self).__init__(message\u003dNone, **kwargs)"},{"line_number":127,"context_line":"        self.authentication \u003d auth_response"},{"line_number":128,"context_line":""},{"line_number":129,"context_line":""},{"line_number":130,"context_line":"class Forbidden(SecurityError):"}],"source_content_type":"text/x-python","patch_set":6,"id":"AAAAM3%2F%2B6Vg%3D","line":127,"updated":"2013-02-14 18:09:34.000000000","message":"extend a common exception class that guarantees an authentication attribute exists","commit_id":"5daf44090947d04c3d330a1aed07cdbf3d57e762"}],"keystone/identity/backends/sql.py":[{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"5634bd71a9a7c40f1bffc87f7db0b18a1010abf5","unresolved":false,"context_lines":[{"line_number":435,"context_line":"        self.get_project(tenant_id)"},{"line_number":436,"context_line":"        metadata_ref \u003d {}"},{"line_number":437,"context_line":"        self._get_user_project_roles(metadata_ref, user_id, tenant_id)"},{"line_number":438,"context_line":"        self._get_user_group_project_roles(metadata_ref, user_id, tenant_id)"},{"line_number":439,"context_line":"        return metadata_ref.get(\u0027roles\u0027, [])"},{"line_number":440,"context_line":""},{"line_number":441,"context_line":"    def add_role_to_user_and_project(self, user_id, tenant_id, role_id):"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2FD9o%3D","line":438,"updated":"2013-02-08 14:18:42.000000000","message":"it looks like this change is worthy of a separate patch?","commit_id":"f03a5dc460399d89064cce9ecf521fad55e26a3a"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"03e156601c97b1b200e8a6e877079ef97fcb25a8","unresolved":false,"context_lines":[{"line_number":435,"context_line":"        self.get_project(tenant_id)"},{"line_number":436,"context_line":"        metadata_ref \u003d {}"},{"line_number":437,"context_line":"        self._get_user_project_roles(metadata_ref, user_id, tenant_id)"},{"line_number":438,"context_line":"        self._get_user_group_project_roles(metadata_ref, user_id, tenant_id)"},{"line_number":439,"context_line":"        return metadata_ref.get(\u0027roles\u0027, [])"},{"line_number":440,"context_line":""},{"line_number":441,"context_line":"    def add_role_to_user_and_project(self, user_id, tenant_id, role_id):"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2FDhc%3D","line":438,"in_reply_to":"AAAAM3%2F%2FD9o%3D","updated":"2013-02-08 19:27:44.000000000","message":"I need them to test my stuff. Might as well do it in this patch.","commit_id":"f03a5dc460399d89064cce9ecf521fad55e26a3a"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"0cc06797a3047b1f3e48cbeb7b3faf0c09fd22af","unresolved":false,"context_lines":[{"line_number":417,"context_line":"        group_refs \u003d self.list_groups_for_user(user_id\u003duser_id)"},{"line_number":418,"context_line":"        for x in group_refs:"},{"line_number":419,"context_line":"            try:"},{"line_number":420,"context_line":"                metadata_ref.update("},{"line_number":421,"context_line":"                    self.get_metadata_ref(group_id\u003dx[\u0027id\u0027],"},{"line_number":422,"context_line":"                                          tenant_id\u003dproject_id))"},{"line_number":423,"context_line":"            except exception.MetadataNotFound:"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAAM3%2F%2B%2B6M%3D","line":420,"updated":"2013-02-12 15:42:20.000000000","message":"i think .update() will result in one group\u0027s roles overriding another group\u0027s roles on the same project -- you need to merge the results a little more carefully to ensure that you get the full set of roles the user has on the project","commit_id":"026f19ee81eeb09f1aba9c287189495627e833aa"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"0cc06797a3047b1f3e48cbeb7b3faf0c09fd22af","unresolved":false,"context_lines":[{"line_number":424,"context_line":"                # no group grant, skip"},{"line_number":425,"context_line":"                pass"},{"line_number":426,"context_line":""},{"line_number":427,"context_line":"    def _get_user_project_roles(self, metadata_ref, user_id, project_id):"},{"line_number":428,"context_line":"        try:"},{"line_number":429,"context_line":"            metadata_ref.update(self.get_metadata(user_id, project_id))"},{"line_number":430,"context_line":"        except exception.MetadataNotFound:"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAAM3%2F%2B%2B58%3D","line":427,"updated":"2013-02-12 15:42:20.000000000","message":"i expect a method called get_* to return something, not to append an object i\u0027m passing in -- maybe have it return a list of role names?","commit_id":"026f19ee81eeb09f1aba9c287189495627e833aa"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"9ce505bf13c6427c10eeebad527910d1bd91e9df","unresolved":false,"context_lines":[{"line_number":209,"context_line":"            # FIXME(gyee): this should really be"},{"line_number":210,"context_line":"            # get_roles_for_user_and_project() after the dusts settle"},{"line_number":211,"context_line":"            if tenant_id not in self.get_projects_for_user(user_id):"},{"line_number":212,"context_line":"                roles \u003d ()"},{"line_number":213,"context_line":"                try:"},{"line_number":214,"context_line":"                    roles \u003d self.get_roles_for_user_and_project(user_id,"},{"line_number":215,"context_line":"                                                                tenant_id)"}],"source_content_type":"text/x-python","patch_set":6,"id":"AAAAM3%2F%2B6VU%3D","line":212,"updated":"2013-02-14 18:09:34.000000000","message":"i don\u0027t know what you\u0027re trying to create here ....\n\nempty tuples must either be...\n\n  tuple()\n  (,)","commit_id":"5daf44090947d04c3d330a1aed07cdbf3d57e762"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"9ce505bf13c6427c10eeebad527910d1bd91e9df","unresolved":false,"context_lines":[{"line_number":217,"context_line":"                    # FIXME(gyee): we should never get into this situation"},{"line_number":218,"context_line":"                    # after user project role migration is completed"},{"line_number":219,"context_line":"                    pass"},{"line_number":220,"context_line":"                if len(roles) \u003d\u003d 0:"},{"line_number":221,"context_line":"                    raise AssertionError(\u0027Invalid tenant\u0027)"},{"line_number":222,"context_line":""},{"line_number":223,"context_line":"            try:"}],"source_content_type":"text/x-python","patch_set":6,"id":"AAAAM3%2F%2B6VY%3D","line":220,"updated":"2013-02-14 18:09:34.000000000","message":"if not len(roles):","commit_id":"5daf44090947d04c3d330a1aed07cdbf3d57e762"},{"author":{"_account_id":2218,"name":"Adam Young","email":"adam@younglogic.com","username":"ayoung"},"change_message_id":"f7c5b5bba57e4077a7700fa85ac89a273661480d","unresolved":false,"context_lines":[{"line_number":215,"context_line":"                    roles \u003d self.get_roles_for_user_and_project(user_id,"},{"line_number":216,"context_line":"                                                                tenant_id)"},{"line_number":217,"context_line":"                except:"},{"line_number":218,"context_line":"                    # FIXME(gyee): we should never get into this situation"},{"line_number":219,"context_line":"                    # after user project role migration is completed"},{"line_number":220,"context_line":"                    pass"},{"line_number":221,"context_line":"                if not len(roles):"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAM3%2F%2B2VY%3D","line":218,"updated":"2013-02-17 06:22:28.000000000","message":"Getting there, bud.","commit_id":"25e13fffbfc512595c1ca19fd378df7d21745056"},{"author":{"_account_id":2340,"name":"Ionut Artarisi","email":"iartarisi@suse.cz","username":"mapleoin"},"change_message_id":"215d4a7df0d854c062b6a62d42b6274884ff187c","unresolved":false,"context_lines":[{"line_number":214,"context_line":"                try:"},{"line_number":215,"context_line":"                    roles \u003d self.get_roles_for_user_and_project(user_id,"},{"line_number":216,"context_line":"                                                                tenant_id)"},{"line_number":217,"context_line":"                except:"},{"line_number":218,"context_line":"                    # FIXME(gyee): we should never get into this situation"},{"line_number":219,"context_line":"                    # after user project role migration is completed"},{"line_number":220,"context_line":"                    pass"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAM3%2F%2ByAw%3D","line":217,"updated":"2013-02-19 12:47:44.000000000","message":"What situation is this? Please don\u0027t leave an empty \"except:\", specify the exception that you\u0027re waiting for (see HACKING).","commit_id":"6c6df626dcc0773c7ae4e8378efdbf8f36763858"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"d5c20ccd065616fdb74bce6665afb523f78e9354","unresolved":false,"context_lines":[{"line_number":214,"context_line":"                try:"},{"line_number":215,"context_line":"                    roles \u003d self.get_roles_for_user_and_project(user_id,"},{"line_number":216,"context_line":"                                                                tenant_id)"},{"line_number":217,"context_line":"                except:"},{"line_number":218,"context_line":"                    # FIXME(gyee): we should never get into this situation"},{"line_number":219,"context_line":"                    # after user project role migration is completed"},{"line_number":220,"context_line":"                    pass"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAM3%2F%2BxbU%3D","line":217,"in_reply_to":"AAAAM3%2F%2ByAw%3D","updated":"2013-02-19 16:03:31.000000000","message":"This code will be short-live. It is intended to be removed once Adam\u0027s user project membership migration is completed. Hence, a FIXME.","commit_id":"6c6df626dcc0773c7ae4e8378efdbf8f36763858"},{"author":{"_account_id":2340,"name":"Ionut Artarisi","email":"iartarisi@suse.cz","username":"mapleoin"},"change_message_id":"215d4a7df0d854c062b6a62d42b6274884ff187c","unresolved":false,"context_lines":[{"line_number":218,"context_line":"                    # FIXME(gyee): we should never get into this situation"},{"line_number":219,"context_line":"                    # after user project role migration is completed"},{"line_number":220,"context_line":"                    pass"},{"line_number":221,"context_line":"                if not len(roles):"},{"line_number":222,"context_line":"                    raise AssertionError(\u0027Invalid tenant\u0027)"},{"line_number":223,"context_line":""},{"line_number":224,"context_line":"            try:"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAM3%2F%2ByA8%3D","line":221,"updated":"2013-02-19 12:47:44.000000000","message":"The len( call is useless here. You can just check if roles is true or not. set() is false.\n\nAlso, can\u0027t this code be in the except branch? That way you can get rid of the roles \u003d set() line, too.","commit_id":"6c6df626dcc0773c7ae4e8378efdbf8f36763858"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"d5c20ccd065616fdb74bce6665afb523f78e9354","unresolved":false,"context_lines":[{"line_number":218,"context_line":"                    # FIXME(gyee): we should never get into this situation"},{"line_number":219,"context_line":"                    # after user project role migration is completed"},{"line_number":220,"context_line":"                    pass"},{"line_number":221,"context_line":"                if not len(roles):"},{"line_number":222,"context_line":"                    raise AssertionError(\u0027Invalid tenant\u0027)"},{"line_number":223,"context_line":""},{"line_number":224,"context_line":"            try:"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAM3%2F%2Bxas%3D","line":221,"in_reply_to":"AAAAM3%2F%2ByA8%3D","updated":"2013-02-19 16:03:31.000000000","message":"Reason I have it outside of except is that the except statement will go away after the user project membership migration.","commit_id":"6c6df626dcc0773c7ae4e8378efdbf8f36763858"},{"author":{"_account_id":2340,"name":"Ionut Artarisi","email":"iartarisi@suse.cz","username":"mapleoin"},"change_message_id":"215d4a7df0d854c062b6a62d42b6274884ff187c","unresolved":false,"context_lines":[{"line_number":431,"context_line":"        membership_refs \u003d query.all()"},{"line_number":432,"context_line":"        return [x.tenant_id for x in membership_refs]"},{"line_number":433,"context_line":""},{"line_number":434,"context_line":"    def _get_user_group_project_roles(self, metadata_ref, user_id, project_id):"},{"line_number":435,"context_line":"        group_refs \u003d self.list_groups_for_user(user_id\u003duser_id)"},{"line_number":436,"context_line":"        for x in group_refs:"},{"line_number":437,"context_line":"            try:"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAM3%2F%2ByAQ%3D","line":434,"updated":"2013-02-19 12:47:44.000000000","message":"These two methods have unintuitive names. \u0027Get\u0027 implies a read operation, but here one of the passed in arguments (metadata_ref) is modified. IMHO modifying the passed in argument reduces readability. Why not return a new dictionary instead?","commit_id":"6c6df626dcc0773c7ae4e8378efdbf8f36763858"},{"author":{"_account_id":2340,"name":"Ionut Artarisi","email":"iartarisi@suse.cz","username":"mapleoin"},"change_message_id":"215d4a7df0d854c062b6a62d42b6274884ff187c","unresolved":false,"context_lines":[{"line_number":454,"context_line":"        metadata_ref \u003d {}"},{"line_number":455,"context_line":"        self._get_user_project_roles(metadata_ref, user_id, tenant_id)"},{"line_number":456,"context_line":"        self._get_user_group_project_roles(metadata_ref, user_id, tenant_id)"},{"line_number":457,"context_line":"        return set(metadata_ref.get(\u0027roles\u0027, []))"},{"line_number":458,"context_line":""},{"line_number":459,"context_line":"    def add_role_to_user_and_project(self, user_id, tenant_id, role_id):"},{"line_number":460,"context_line":"        self.get_user(user_id)"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAM3%2F%2ByAg%3D","line":457,"updated":"2013-02-19 12:47:44.000000000","message":"Doesn\u0027t this break the existing Identity API? The other backends return a list here. Do you want to do list(set(metdata...)) instead?","commit_id":"6c6df626dcc0773c7ae4e8378efdbf8f36763858"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"d5c20ccd065616fdb74bce6665afb523f78e9354","unresolved":false,"context_lines":[{"line_number":454,"context_line":"        metadata_ref \u003d {}"},{"line_number":455,"context_line":"        self._get_user_project_roles(metadata_ref, user_id, tenant_id)"},{"line_number":456,"context_line":"        self._get_user_group_project_roles(metadata_ref, user_id, tenant_id)"},{"line_number":457,"context_line":"        return set(metadata_ref.get(\u0027roles\u0027, []))"},{"line_number":458,"context_line":""},{"line_number":459,"context_line":"    def add_role_to_user_and_project(self, user_id, tenant_id, role_id):"},{"line_number":460,"context_line":"        self.get_user(user_id)"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAM3%2F%2Bxao%3D","line":457,"in_reply_to":"AAAAM3%2F%2ByAg%3D","updated":"2013-02-19 16:03:31.000000000","message":"Apparently none of the unit tests failed. :) But yeah, list() make sense.","commit_id":"6c6df626dcc0773c7ae4e8378efdbf8f36763858"}],"keystone/identity/controllers.py":[{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"5634bd71a9a7c40f1bffc87f7db0b18a1010abf5","unresolved":false,"context_lines":[{"line_number":479,"context_line":"    @controller.protected"},{"line_number":480,"context_line":"    def get_project_by_name(self, context, project_name):"},{"line_number":481,"context_line":"        return {\u0027project\u0027: self.identity_api.get_project_by_name("},{"line_number":482,"context_line":"            context, project_name)}"},{"line_number":483,"context_line":""},{"line_number":484,"context_line":"    @controller.protected"},{"line_number":485,"context_line":"    def update_project(self, context, project_id, project):"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2FD9s%3D","line":482,"updated":"2013-02-08 14:18:42.000000000","message":"-1; list projects should be filterable by name, but there\u0027s no reason to expose this at the controller level?","commit_id":"f03a5dc460399d89064cce9ecf521fad55e26a3a"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"03e156601c97b1b200e8a6e877079ef97fcb25a8","unresolved":false,"context_lines":[{"line_number":479,"context_line":"    @controller.protected"},{"line_number":480,"context_line":"    def get_project_by_name(self, context, project_name):"},{"line_number":481,"context_line":"        return {\u0027project\u0027: self.identity_api.get_project_by_name("},{"line_number":482,"context_line":"            context, project_name)}"},{"line_number":483,"context_line":""},{"line_number":484,"context_line":"    @controller.protected"},{"line_number":485,"context_line":"    def update_project(self, context, project_id, project):"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2FDhU%3D","line":482,"in_reply_to":"AAAAM3%2F%2FD9s%3D","updated":"2013-02-08 19:27:44.000000000","message":"Sure, I am OK with the filtering approach.","commit_id":"f03a5dc460399d89064cce9ecf521fad55e26a3a"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"0cc06797a3047b1f3e48cbeb7b3faf0c09fd22af","unresolved":false,"context_lines":[{"line_number":483,"context_line":"        return ProjectV3.wrap_member(context, ref)"},{"line_number":484,"context_line":""},{"line_number":485,"context_line":"    @controller.protected"},{"line_number":486,"context_line":"    def get_project_by_name(self, context, project_name):"},{"line_number":487,"context_line":"        return {\u0027project\u0027: self.identity_api.get_project_by_name("},{"line_number":488,"context_line":"            context, project_name)}"},{"line_number":489,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAAM3%2F%2B%2B7A%3D","line":486,"updated":"2013-02-12 15:42:20.000000000","message":"-2; this is awfully close to exposing an undocumented call, please revert this change completely","commit_id":"026f19ee81eeb09f1aba9c287189495627e833aa"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"b24090c25b4b8f300b29ee344433cee31bd56e09","unresolved":false,"context_lines":[{"line_number":483,"context_line":"        return ProjectV3.wrap_member(context, ref)"},{"line_number":484,"context_line":""},{"line_number":485,"context_line":"    @controller.protected"},{"line_number":486,"context_line":"    def get_project_by_name(self, context, project_name):"},{"line_number":487,"context_line":"        return {\u0027project\u0027: self.identity_api.get_project_by_name("},{"line_number":488,"context_line":"            context, project_name)}"},{"line_number":489,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAAM3%2F%2B%2Bnc%3D","line":486,"in_reply_to":"AAAAM3%2F%2B%2B28%3D","updated":"2013-02-12 17:30:52.000000000","message":"...not in the v3 controllers we don\u0027t...so agree with Dolph, lets not set these up for external exposure","commit_id":"026f19ee81eeb09f1aba9c287189495627e833aa"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"2ad0614b662b5a193961abd6437f32848fb0dd0c","unresolved":false,"context_lines":[{"line_number":483,"context_line":"        return ProjectV3.wrap_member(context, ref)"},{"line_number":484,"context_line":""},{"line_number":485,"context_line":"    @controller.protected"},{"line_number":486,"context_line":"    def get_project_by_name(self, context, project_name):"},{"line_number":487,"context_line":"        return {\u0027project\u0027: self.identity_api.get_project_by_name("},{"line_number":488,"context_line":"            context, project_name)}"},{"line_number":489,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAAM3%2F%2B%2B28%3D","line":486,"in_reply_to":"AAAAM3%2F%2B%2B7A%3D","updated":"2013-02-12 15:54:16.000000000","message":"But we also have get_user_by_name()? I am trying to do the same for projects. Should we get rid of get_user_by_name() as well?","commit_id":"026f19ee81eeb09f1aba9c287189495627e833aa"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"c294933d3d90ce3211b9e97066402566bdbac728","unresolved":false,"context_lines":[{"line_number":483,"context_line":"        return ProjectV3.wrap_member(context, ref)"},{"line_number":484,"context_line":""},{"line_number":485,"context_line":"    @controller.protected"},{"line_number":486,"context_line":"    def get_project_by_name(self, context, project_name):"},{"line_number":487,"context_line":"        return {\u0027project\u0027: self.identity_api.get_project_by_name("},{"line_number":488,"context_line":"            context, project_name)}"},{"line_number":489,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAAM3%2F%2B%2BUM%3D","line":486,"in_reply_to":"AAAAM3%2F%2B%2Bnc%3D","updated":"2013-02-12 19:56:43.000000000","message":"+1 ^^ get user/tenant by name are exposed in v2 as part of the (I think) OS-KSADM contract, but this call wouldn\u0027t even make sense in v3","commit_id":"026f19ee81eeb09f1aba9c287189495627e833aa"}],"keystone/middleware/core.py":[{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"0cc06797a3047b1f3e48cbeb7b3faf0c09fd22af","unresolved":false,"context_lines":[{"line_number":49,"context_line":"        context \u003d request.environ.get(CONTEXT_ENV, {})"},{"line_number":50,"context_line":"        context[\u0027token_id\u0027] \u003d token"},{"line_number":51,"context_line":"        if SUBJECT_TOKEN_HEADER in request.headers:"},{"line_number":52,"context_line":"            context[\u0027subject_token_id\u0027] \u003d \\"},{"line_number":53,"context_line":"                request.headers.get(SUBJECT_TOKEN_HEADER)"},{"line_number":54,"context_line":"        request.environ[CONTEXT_ENV] \u003d context"},{"line_number":55,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAAM3%2F%2B%2B8I%3D","line":52,"updated":"2013-02-12 15:42:20.000000000","message":"(HACKING) wrap in parens instead of using backslash continuations\n\n  context[\u0027subject_token_id\u0027] \u003d (\n    request.headers.get(SUBJECT_TOKEN_HEADER))","commit_id":"026f19ee81eeb09f1aba9c287189495627e833aa"}],"keystone/openstack/common/policy.py":[{"author":{"_account_id":2218,"name":"Adam Young","email":"adam@younglogic.com","username":"ayoung"},"change_message_id":"33ba53cf7f51f56fa738d0f170490b3ec11f3dfd","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# vim: tabstop\u003d4 shiftwidth\u003d4 softtabstop\u003d4"},{"line_number":2,"context_line":""},{"line_number":3,"context_line":"# Copyright (c) 2012 OpenStack, LLC."},{"line_number":4,"context_line":"# All Rights Reserved."}],"source_content_type":"text/x-python","patch_set":17,"id":"AAAAM3%2F%2BvcY%3D","line":1,"updated":"2013-02-20 14:59:29.000000000","message":"Is this just the file out of common?  I thought we already had a copy.","commit_id":"383a77cbdf12c451f1032ecf1f5e8a35b5354847"}],"tests/policy.json":[{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"cbd0f0238082ef2e249165ca6e41204bf6c355ae","unresolved":false,"context_lines":[{"line_number":1,"context_line":"{"},{"line_number":2,"context_line":"    \"admin_required\": [[\"role:admin\"], [\"is_admin:1\"]],"},{"line_number":3,"context_line":""},{"line_number":4,"context_line":"    \"identity:get_service\": [[\"rule:admin_required\"]],"}],"source_content_type":"application/json","patch_set":17,"id":"AAAAM3%2F%2Bu3E%3D","line":1,"updated":"2013-02-20 14:00:18.000000000","message":"delete this entire file\n\nin keystone.test.TestCase.setUp, add\n\n  self.opt(policy_file\u003detcdir(\u0027policy.json\u0027))\n\nand get this for free","commit_id":"383a77cbdf12c451f1032ecf1f5e8a35b5354847"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"5f8f33cdbcfc83b6f87ce4cbd535b9e42d567e29","unresolved":false,"context_lines":[{"line_number":1,"context_line":"{"},{"line_number":2,"context_line":"    \"admin_required\": [[\"role:admin\"], [\"is_admin:1\"]],"},{"line_number":3,"context_line":""},{"line_number":4,"context_line":"    \"identity:get_service\": [[\"rule:admin_required\"]],"}],"source_content_type":"application/json","patch_set":17,"id":"AAAAM3%2F%2Buss%3D","line":1,"in_reply_to":"AAAAM3%2F%2Bu3E%3D","updated":"2013-02-20 15:38:15.000000000","message":"Apply this diff for the above:\n\n  http://paste.openstack.org/raw/32078/","commit_id":"383a77cbdf12c451f1032ecf1f5e8a35b5354847"}],"tests/test_auth_plugin.conf":[{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"9ce505bf13c6427c10eeebad527910d1bd91e9df","unresolved":false,"context_lines":[{"line_number":1,"context_line":"[auth]"},{"line_number":2,"context_line":"methods \u003d password,token,simple-challenge-response"},{"line_number":3,"context_line":"password \u003d keystone.auth.methods.password.Password"},{"line_number":4,"context_line":"token \u003d keystone.auth.methods.token.Token"},{"line_number":5,"context_line":"simple-challenge-response \u003d challenge_response_method.SimpleChallengeResponse"},{"line_number":6,"context_line":""}],"source_content_type":"text/plain","patch_set":6,"id":"AAAAM3%2F%2B6VI%3D","line":4,"updated":"2013-02-14 18:09:34.000000000","message":"exclude the password and token lines, as they\u0027re just default anyway","commit_id":"5daf44090947d04c3d330a1aed07cdbf3d57e762"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"9ce505bf13c6427c10eeebad527910d1bd91e9df","unresolved":false,"context_lines":[{"line_number":2,"context_line":"methods \u003d password,token,simple-challenge-response"},{"line_number":3,"context_line":"password \u003d keystone.auth.methods.password.Password"},{"line_number":4,"context_line":"token \u003d keystone.auth.methods.token.Token"},{"line_number":5,"context_line":"simple-challenge-response \u003d challenge_response_method.SimpleChallengeResponse"},{"line_number":6,"context_line":""}],"source_content_type":"text/plain","patch_set":6,"id":"AAAAM3%2F%2B6VE%3D","line":5,"updated":"2013-02-14 18:09:34.000000000","message":"is this a package name? really confused here","commit_id":"5daf44090947d04c3d330a1aed07cdbf3d57e762"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"9ce505bf13c6427c10eeebad527910d1bd91e9df","unresolved":false,"context_lines":[{"line_number":3,"context_line":"password \u003d keystone.auth.methods.password.Password"},{"line_number":4,"context_line":"token \u003d keystone.auth.methods.token.Token"},{"line_number":5,"context_line":"simple-challenge-response \u003d challenge_response_method.SimpleChallengeResponse"},{"line_number":6,"context_line":""}],"source_content_type":"text/plain","patch_set":6,"id":"AAAAM3%2F%2B6VA%3D","line":6,"updated":"2013-02-14 18:09:34.000000000","message":"remove the whitespace at end of file","commit_id":"5daf44090947d04c3d330a1aed07cdbf3d57e762"},{"author":{"_account_id":6460,"name":"Brad Topol","email":"btopol@us.ibm.com","username":"btopol"},"change_message_id":"53884e9038c25dfd56d2babd0624a84b7c27d73a","unresolved":false,"context_lines":[{"line_number":1,"context_line":"[auth]"},{"line_number":2,"context_line":"methods \u003d password,token,simple-challenge-response"},{"line_number":3,"context_line":"simple-challenge-response \u003d challenge_response_method.SimpleChallengeResponse"}],"source_content_type":"text/plain","patch_set":10,"id":"AAAAM3%2F%2Bxdg%3D","line":2,"updated":"2013-02-19 15:54:17.000000000","message":"In this example you are enable all 3 plugins.  What is unclear to me is the trigger model.   How is it declared when the password plugin will be invoked, when the token plugin will be invoked, and when the custom simple-challenge-response plugin will be invoked.  How the orchestration is managed and the semantics (does it try all three???) needs to be clearly documented.","commit_id":"6c6df626dcc0773c7ae4e8378efdbf8f36763858"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"d5c20ccd065616fdb74bce6665afb523f78e9354","unresolved":false,"context_lines":[{"line_number":1,"context_line":"[auth]"},{"line_number":2,"context_line":"methods \u003d password,token,simple-challenge-response"},{"line_number":3,"context_line":"simple-challenge-response \u003d challenge_response_method.SimpleChallengeResponse"}],"source_content_type":"text/plain","patch_set":10,"id":"AAAAM3%2F%2BxZM%3D","line":2,"in_reply_to":"AAAAM3%2F%2Bxdg%3D","updated":"2013-02-19 16:03:31.000000000","message":"They are documented in configuration.rst I think.","commit_id":"6c6df626dcc0773c7ae4e8378efdbf8f36763858"}],"tests/test_auth_plugin.py":[{"author":{"_account_id":6460,"name":"Brad Topol","email":"btopol@us.ibm.com","username":"btopol"},"change_message_id":"e46de455d4be952ccf5a79dd60c19ebdf25dcad6","unresolved":false,"context_lines":[{"line_number":24,"context_line":"METHOD_NAME \u003d \u0027simple-challenge-response\u0027"},{"line_number":25,"context_line":""},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"class SimpleChallengeResponse(auth.AuthMethodHandler):"},{"line_number":28,"context_line":"    def authenticate(self, context, auth_info, user_context):"},{"line_number":29,"context_line":"        return {\"challenge\": \"What\u0027s the name of your high school?\"}"},{"line_number":30,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"AAAAM3%2F%2B6UY%3D","line":27,"updated":"2013-02-14 18:11:25.000000000","message":"Might be helpful to have an example of the more complicated AuthMethodHandler that demonstrates how a plugin can be written to do multi-step authentication.","commit_id":"5daf44090947d04c3d330a1aed07cdbf3d57e762"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"9ce505bf13c6427c10eeebad527910d1bd91e9df","unresolved":false,"context_lines":[{"line_number":43,"context_line":"        self.api \u003d auth.controllers.Auth()"},{"line_number":44,"context_line":""},{"line_number":45,"context_line":"    def test_unsupported_auth_method(self):"},{"line_number":46,"context_line":"        auth_json \u003d {\u0027methods\u0027: [\u0027abc\u0027]}"},{"line_number":47,"context_line":"        auth_json[\u0027abc\u0027] \u003d {\u0027test\u0027: \u0027test\u0027}"},{"line_number":48,"context_line":"        auth_json \u003d {\u0027authentication\u0027: auth_json}"},{"line_number":49,"context_line":"        self.assertRaises(exception.AuthMethodNotSupported,"}],"source_content_type":"text/x-python","patch_set":6,"id":"AAAAM3%2F%2B6U8%3D","line":46,"updated":"2013-02-14 18:09:34.000000000","message":"use uuid\u0027s to illustrate arbitrary values throughout","commit_id":"5daf44090947d04c3d330a1aed07cdbf3d57e762"},{"author":{"_account_id":6,"name":"Joe Heck","email":"heckj@mac.com","username":"heckj"},"change_message_id":"5b2c6c596329f210a9bc0abf3661cde2f73a7c58","unresolved":false,"context_lines":[{"line_number":40,"context_line":"            return {\"challenge\": \"What\u0027s the name of your high school?\"}"},{"line_number":41,"context_line":""},{"line_number":42,"context_line":""},{"line_number":43,"context_line":"class TestAuthPlugin(test.TestCase):"},{"line_number":44,"context_line":"    def setUp(self):"},{"line_number":45,"context_line":"        super(TestAuthPlugin, self).setUp()"},{"line_number":46,"context_line":"        self.config(["}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAM3%2F%2B3Ww%3D","line":43,"updated":"2013-02-16 01:56:22.000000000","message":"if we\u0027re going to mandate side effects in the handler, then we should be testing for them here - user_name and method being explicitly added to the auth_context (if I read it right). Otherwise we\u0027re sure to have incorrect plugins that pass the tests, but aren\u0027t \"right\"","commit_id":"25e13fffbfc512595c1ca19fd378df7d21745056"},{"author":{"_account_id":2218,"name":"Adam Young","email":"adam@younglogic.com","username":"ayoung"},"change_message_id":"f7c5b5bba57e4077a7700fa85ac89a273661480d","unresolved":false,"context_lines":[{"line_number":40,"context_line":"            return {\"challenge\": \"What\u0027s the name of your high school?\"}"},{"line_number":41,"context_line":""},{"line_number":42,"context_line":""},{"line_number":43,"context_line":"class TestAuthPlugin(test.TestCase):"},{"line_number":44,"context_line":"    def setUp(self):"},{"line_number":45,"context_line":"        super(TestAuthPlugin, self).setUp()"},{"line_number":46,"context_line":"        self.config(["}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAM3%2F%2B2Vc%3D","line":43,"in_reply_to":"AAAAM3%2F%2B3Qk%3D","updated":"2013-02-17 06:22:28.000000000","message":"All he is saying is we need a test method that gets run against all plugins that we ship that makes sure it provides the right side effects.","commit_id":"25e13fffbfc512595c1ca19fd378df7d21745056"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"a8b3a625faa7cfcbc18def49ec508c802de1e30e","unresolved":false,"context_lines":[{"line_number":40,"context_line":"            return {\"challenge\": \"What\u0027s the name of your high school?\"}"},{"line_number":41,"context_line":""},{"line_number":42,"context_line":""},{"line_number":43,"context_line":"class TestAuthPlugin(test.TestCase):"},{"line_number":44,"context_line":"    def setUp(self):"},{"line_number":45,"context_line":"        super(TestAuthPlugin, self).setUp()"},{"line_number":46,"context_line":"        self.config(["}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAM3%2F%2B3Qk%3D","line":43,"in_reply_to":"AAAAM3%2F%2B3Ww%3D","updated":"2013-02-16 03:00:44.000000000","message":"I don\u0027t think we can effectively police all plugins. All we can do is to do some very basic checks. Like PAM modules, plugins can shoot themselves in the foot if they really wanted. No difference than say a dynamically loaded library causes memory corruption.","commit_id":"25e13fffbfc512595c1ca19fd378df7d21745056"},{"author":{"_account_id":6,"name":"Joe Heck","email":"heckj@mac.com","username":"heckj"},"change_message_id":"5b2c6c596329f210a9bc0abf3661cde2f73a7c58","unresolved":false,"context_lines":[{"line_number":99,"context_line":"                          self.api.authenticate,"},{"line_number":100,"context_line":"                          {},"},{"line_number":101,"context_line":"                          auth_info,"},{"line_number":102,"context_line":"                          auth_context)"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAM3%2F%2B3Ws%3D","line":102,"updated":"2013-02-16 01:56:22.000000000","message":"expected to have tests that explicitly work the \"token\" and \"password\" auth handlers","commit_id":"25e13fffbfc512595c1ca19fd378df7d21745056"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"a8b3a625faa7cfcbc18def49ec508c802de1e30e","unresolved":false,"context_lines":[{"line_number":99,"context_line":"                          self.api.authenticate,"},{"line_number":100,"context_line":"                          {},"},{"line_number":101,"context_line":"                          auth_info,"},{"line_number":102,"context_line":"                          auth_context)"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAM3%2F%2B3Qo%3D","line":102,"in_reply_to":"AAAAM3%2F%2B3Ws%3D","updated":"2013-02-16 03:00:44.000000000","message":"token and password handlers are invoked in test_v3_auth.py.","commit_id":"25e13fffbfc512595c1ca19fd378df7d21745056"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"c0fd66948f15b497620658195a357ad3b672df21","unresolved":false,"context_lines":[{"line_number":25,"context_line":""},{"line_number":26,"context_line":"# for testing purposes only"},{"line_number":27,"context_line":"METHOD_NAME \u003d \u0027simple-challenge-response\u0027"},{"line_number":28,"context_line":"EXPECTED_RESPONSE \u003d \u0027Polk High School\u0027"},{"line_number":29,"context_line":"DEMO_USER_ID \u003d uuid.uuid4().hex"},{"line_number":30,"context_line":""},{"line_number":31,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2Bz48%3D","line":28,"updated":"2013-02-18 22:33:21.000000000","message":"uuid value as well?","commit_id":"a33dd427322b85e7a883e19e260539f60e4accad"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"c0fd66948f15b497620658195a357ad3b672df21","unresolved":false,"context_lines":[{"line_number":60,"context_line":"        auth_json \u003d {\u0027authentication\u0027: auth_json}"},{"line_number":61,"context_line":"        self.assertRaises(exception.AuthMethodNotSupported,"},{"line_number":62,"context_line":"                          auth.controllers.AuthInfo,"},{"line_number":63,"context_line":"                          None,"},{"line_number":64,"context_line":"                          auth_json)"},{"line_number":65,"context_line":""},{"line_number":66,"context_line":"    def test_addition_auth_steps(self):"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2Bz5Q%3D","line":63,"updated":"2013-02-18 22:33:21.000000000","message":"i feel like i\u0027ve seen other tests passing an empty dictionary for context","commit_id":"a33dd427322b85e7a883e19e260539f60e4accad"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"c0fd66948f15b497620658195a357ad3b672df21","unresolved":false,"context_lines":[{"line_number":88,"context_line":"        self.api.authenticate({}, auth_info, auth_context)"},{"line_number":89,"context_line":"        self.assertEqual(auth_context[\u0027user_id\u0027], DEMO_USER_ID)"},{"line_number":90,"context_line":""},{"line_number":91,"context_line":"        # test incorrect reponse"},{"line_number":92,"context_line":"        auth_json \u003d {\u0027methods\u0027: [\u0027simple-challenge-response\u0027]}"},{"line_number":93,"context_line":"        auth_json[\u0027simple-challenge-response\u0027] \u003d {"},{"line_number":94,"context_line":"            \u0027response\u0027: uuid.uuid4().hex}"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2Bz5Y%3D","line":91,"updated":"2013-02-18 22:33:21.000000000","message":"response","commit_id":"a33dd427322b85e7a883e19e260539f60e4accad"},{"author":{"_account_id":2340,"name":"Ionut Artarisi","email":"iartarisi@suse.cz","username":"mapleoin"},"change_message_id":"c4f6949efd7663cde129c633aa34e079d3facc46","unresolved":false,"context_lines":[{"line_number":78,"context_line":"            self.assertTrue(METHOD_NAME in e.authentication)"},{"line_number":79,"context_line":"            self.assertTrue(\u0027challenge\u0027 in e.authentication[METHOD_NAME])"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":"        # test correct response"},{"line_number":82,"context_line":"        auth_data \u003d {\u0027methods\u0027: [\u0027simple-challenge-response\u0027]}"},{"line_number":83,"context_line":"        auth_data[\u0027simple-challenge-response\u0027] \u003d {"},{"line_number":84,"context_line":"            \u0027response\u0027: EXPECTED_RESPONSE}"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAM3%2F%2Bxms%3D","line":81,"updated":"2013-02-19 15:10:53.000000000","message":"These look like they would be better as separate tests.","commit_id":"6c6df626dcc0773c7ae4e8378efdbf8f36763858"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"d5c20ccd065616fdb74bce6665afb523f78e9354","unresolved":false,"context_lines":[{"line_number":78,"context_line":"            self.assertTrue(METHOD_NAME in e.authentication)"},{"line_number":79,"context_line":"            self.assertTrue(\u0027challenge\u0027 in e.authentication[METHOD_NAME])"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":"        # test correct response"},{"line_number":82,"context_line":"        auth_data \u003d {\u0027methods\u0027: [\u0027simple-challenge-response\u0027]}"},{"line_number":83,"context_line":"        auth_data[\u0027simple-challenge-response\u0027] \u003d {"},{"line_number":84,"context_line":"            \u0027response\u0027: EXPECTED_RESPONSE}"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAM3%2F%2Bxc0%3D","line":81,"in_reply_to":"AAAAM3%2F%2Bxms%3D","updated":"2013-02-19 16:03:31.000000000","message":"This is a test for a multiple step auths. Doing it in a separate test would require the exact same setup steps in the beginning. Not worth the tradeoff.","commit_id":"6c6df626dcc0773c7ae4e8378efdbf8f36763858"}],"tests/test_v3.py":[{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"5df5ae98cfbe15955247ee832f380373af8c3b9b","unresolved":false,"context_lines":[{"line_number":95,"context_line":"        r \u003d self.admin_request("},{"line_number":96,"context_line":"            method\u003d\u0027POST\u0027,"},{"line_number":97,"context_line":"            path\u003d\u0027/v3/auth/tokens\u0027,"},{"line_number":98,"context_line":"            token\u003d\u0027ADMIN\u0027,"},{"line_number":99,"context_line":"            body\u003d{"},{"line_number":100,"context_line":"                \u0027authentication\u0027: {"},{"line_number":101,"context_line":"                    \u0027methods\u0027: [\u0027password\u0027],"}],"source_content_type":"text/x-python","patch_set":13,"id":"AAAAM3%2F%2BwtA%3D","line":98,"updated":"2013-02-19 19:54:30.000000000","message":"you shouldn\u0027t have to pass a token to authenticate","commit_id":"2149b07c63ef1a09f1ca809980f0dedce3d655e5"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"fb709b0e856328af67daaa2ee706e118a86341bd","unresolved":false,"context_lines":[{"line_number":117,"context_line":"        return r.getheader(\u0027X-Subject-Token\u0027)"},{"line_number":118,"context_line":""},{"line_number":119,"context_line":"    def v3_request(self, path, is_admin\u003dTrue, **kwargs):"},{"line_number":120,"context_line":"        token \u003d \u0027ADMIN\u0027 if is_admin else self.get_scoped_token()"},{"line_number":121,"context_line":"        path \u003d \u0027/v3\u0027 + path"},{"line_number":122,"context_line":"        return self.admin_request("},{"line_number":123,"context_line":"            path\u003dpath,"}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAAM3%2F%2Bwe0%3D","line":120,"updated":"2013-02-19 21:13:27.000000000","message":"this is still bypassing auth","commit_id":"13566a6013631ed5256581c208d9ee666ca4ffb5"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"fb709b0e856328af67daaa2ee706e118a86341bd","unresolved":false,"context_lines":[{"line_number":124,"context_line":"            token\u003dtoken,"},{"line_number":125,"context_line":"            **kwargs)"},{"line_number":126,"context_line":""},{"line_number":127,"context_line":"    def get(self, path, is_admin\u003dTrue, **kwargs):"},{"line_number":128,"context_line":"        return self.v3_request(method\u003d\u0027GET\u0027, path\u003dpath, **kwargs)"},{"line_number":129,"context_line":""},{"line_number":130,"context_line":"    def head(self, path, is_admin\u003dTrue, **kwargs):"}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAAM3%2F%2Bwew%3D","line":127,"updated":"2013-02-19 21:13:27.000000000","message":"is_admin is a hack to bypass auth","commit_id":"13566a6013631ed5256581c208d9ee666ca4ffb5"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"4809e73c09747a710991b0aeded1385bfe2bac44","unresolved":false,"context_lines":[{"line_number":117,"context_line":"        return r.getheader(\u0027X-Subject-Token\u0027)"},{"line_number":118,"context_line":""},{"line_number":119,"context_line":"    def v3_request(self, path, is_admin\u003dTrue, **kwargs):"},{"line_number":120,"context_line":"        token \u003d \u0027ADMIN\u0027 if is_admin else self.get_scoped_token()"},{"line_number":121,"context_line":"        path \u003d \u0027/v3\u0027 + path"},{"line_number":122,"context_line":"        return self.admin_request("},{"line_number":123,"context_line":"            path\u003dpath,"}],"source_content_type":"text/x-python","patch_set":16,"id":"AAAAM3%2F%2BwKA%3D","line":120,"updated":"2013-02-19 23:08:50.000000000","message":"the \u0027is_admin\u0027 stuff needs to be removed -- bypassing authentication radically reduces coverage","commit_id":"8cba920518ddd87ec99ce464f666e59c1ecd3abf"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"cbd0f0238082ef2e249165ca6e41204bf6c355ae","unresolved":false,"context_lines":[{"line_number":20,"context_line":"            test.testsdir(\u0027backend_sql_disk.conf\u0027)])"},{"line_number":21,"context_line":"        sql_util.setup_test_database()"},{"line_number":22,"context_line":"        self.load_backends()"},{"line_number":23,"context_line":"        self.load_fixtures(default_fixtures)"},{"line_number":24,"context_line":"        self.identity_api.add_role_to_user_and_project("},{"line_number":25,"context_line":"            self.user_foo[\u0027id\u0027], self.tenant_bar[\u0027id\u0027],"},{"line_number":26,"context_line":"            self.role_admin[\u0027id\u0027])"}],"source_content_type":"text/x-python","patch_set":17,"id":"AAAAM3%2F%2Bu3U%3D","line":23,"updated":"2013-02-20 14:00:18.000000000","message":"those fixtures add a huge amount of completely unnecessary overhead to these tests\n\nmove the domain, project, user, role and role grant from keystone_identity to the end of this setup method, and override the role name with \u0027admin\u0027 and then self.user with be admin across all v3 tests\n\nleave groups and credentials in the identity setup method\n\nalso still include the role_keystone_admin -\u003e role_admin changes as their more representative of what our use case anyway","commit_id":"383a77cbdf12c451f1032ecf1f5e8a35b5354847"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"75e185960b3a2585a2b7c49f2d84b38e16c2df25","unresolved":false,"context_lines":[{"line_number":182,"context_line":"        If a reference is provided, the entity will also be compared against"},{"line_number":183,"context_line":"        the reference."},{"line_number":184,"context_line":"        \"\"\""},{"line_number":185,"context_line":"        keys \u003d [\u0027name\u0027, \u0027description\u0027, \u0027enabled\u0027]"},{"line_number":186,"context_line":""},{"line_number":187,"context_line":"        for k in [\u0027id\u0027] + keys:"},{"line_number":188,"context_line":"            msg \u003d \u0027%s unexpectedly None in %s\u0027 % (k, entity)"}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAAM3%2F%2BuEo%3D","side":"PARENT","line":185,"updated":"2013-02-20 19:27:56.000000000","message":"-1 this is removing api-wide assertions","commit_id":"d036db145d51f8b134ffa36165065a8986e4f8a1"}],"tests/test_v3_auth.py":[{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"9ce505bf13c6427c10eeebad527910d1bd91e9df","unresolved":false,"context_lines":[{"line_number":144,"context_line":"        # need to reset the plug-ins"},{"line_number":145,"context_line":"        auth.controllers.AUTH_METHODS \u003d {}"},{"line_number":146,"context_line":""},{"line_number":147,"context_line":"    def assert_unscoped_token(self, token):"},{"line_number":148,"context_line":"        self.assertEqual([], token[\u0027user\u0027][\u0027roles\u0027])"},{"line_number":149,"context_line":"        self.assertEqual(self.user_id, token[\u0027user\u0027][\u0027id\u0027])"},{"line_number":150,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"AAAAM3%2F%2B6U0%3D","line":147,"updated":"2013-02-14 18:09:34.000000000","message":"prefer following unittest\u0027s method naming... also include what you\u0027re asserting (e.g. that it\u0027s \"valid\")\n\n  assertValidUnscopedToken","commit_id":"5daf44090947d04c3d330a1aed07cdbf3d57e762"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"9ce505bf13c6427c10eeebad527910d1bd91e9df","unresolved":false,"context_lines":[{"line_number":149,"context_line":"        self.assertEqual(self.user_id, token[\u0027user\u0027][\u0027id\u0027])"},{"line_number":150,"context_line":""},{"line_number":151,"context_line":"    def assert_scoped_token(self, token):"},{"line_number":152,"context_line":"        self.assertNotEqual([], token[\u0027user\u0027][\u0027roles\u0027])"},{"line_number":153,"context_line":"        self.assertEqual(self.user_id, token[\u0027user\u0027][\u0027id\u0027])"},{"line_number":154,"context_line":"        self.assertEqual(self.role_id, token[\u0027user\u0027][\u0027roles\u0027][0][\u0027id\u0027])"},{"line_number":155,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"AAAAM3%2F%2B6Uw%3D","line":152,"updated":"2013-02-14 18:09:34.000000000","message":"assertTrue(token[\u0027roles\u0027])\n\nnote i removed user ^","commit_id":"5daf44090947d04c3d330a1aed07cdbf3d57e762"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"9ce505bf13c6427c10eeebad527910d1bd91e9df","unresolved":false,"context_lines":[{"line_number":151,"context_line":"    def assert_scoped_token(self, token):"},{"line_number":152,"context_line":"        self.assertNotEqual([], token[\u0027user\u0027][\u0027roles\u0027])"},{"line_number":153,"context_line":"        self.assertEqual(self.user_id, token[\u0027user\u0027][\u0027id\u0027])"},{"line_number":154,"context_line":"        self.assertEqual(self.role_id, token[\u0027user\u0027][\u0027roles\u0027][0][\u0027id\u0027])"},{"line_number":155,"context_line":""},{"line_number":156,"context_line":"    def assertValidErrorResponse(self, r):"},{"line_number":157,"context_line":"        pass"}],"source_content_type":"text/x-python","patch_set":6,"id":"AAAAM3%2F%2B6Ug%3D","line":154,"updated":"2013-02-14 18:09:34.000000000","message":"unscoped and scoped assertion should both call a common method to assert things like has \"expires\", has valid \"user\", including domain element, etc","commit_id":"5daf44090947d04c3d330a1aed07cdbf3d57e762"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"9ce505bf13c6427c10eeebad527910d1bd91e9df","unresolved":false,"context_lines":[{"line_number":164,"context_line":"        \"\"\""},{"line_number":165,"context_line":"        def normalize(token):"},{"line_number":166,"context_line":"            del token[\u0027token\u0027][\u0027expires\u0027]"},{"line_number":167,"context_line":"            del token[\u0027token\u0027][\u0027issued_at\u0027]"},{"line_number":168,"context_line":"            return token"},{"line_number":169,"context_line":""},{"line_number":170,"context_line":"        self.assertCloseEnoughForGovernmentWork("}],"source_content_type":"text/x-python","patch_set":6,"id":"AAAAM3%2F%2B6UM%3D","line":167,"updated":"2013-02-14 18:09:34.000000000","message":"expires and issued_at need to use the same naming convention; spec needs to be revised obviously","commit_id":"5daf44090947d04c3d330a1aed07cdbf3d57e762"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"9ce505bf13c6427c10eeebad527910d1bd91e9df","unresolved":false,"context_lines":[{"line_number":169,"context_line":""},{"line_number":170,"context_line":"        self.assertCloseEnoughForGovernmentWork("},{"line_number":171,"context_line":"            timeutils.parse_isotime(a[\u0027token\u0027][\u0027expires\u0027]),"},{"line_number":172,"context_line":"            timeutils.parse_isotime(b[\u0027token\u0027][\u0027expires\u0027]))"},{"line_number":173,"context_line":"        self.assertCloseEnoughForGovernmentWork("},{"line_number":174,"context_line":"            timeutils.parse_isotime(a[\u0027token\u0027][\u0027issued_at\u0027]),"},{"line_number":175,"context_line":"            timeutils.parse_isotime(b[\u0027token\u0027][\u0027issued_at\u0027]))"}],"source_content_type":"text/x-python","patch_set":6,"id":"AAAAM3%2F%2B6UU%3D","line":172,"updated":"2013-02-14 18:09:34.000000000","message":"expires is at the root level","commit_id":"5daf44090947d04c3d330a1aed07cdbf3d57e762"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"9ce505bf13c6427c10eeebad527910d1bd91e9df","unresolved":false,"context_lines":[{"line_number":182,"context_line":""},{"line_number":183,"context_line":"    def test_missing_auth_methods(self):"},{"line_number":184,"context_line":"        auth_json \u003d {\u0027authentication\u0027: {}}"},{"line_number":185,"context_line":"        auth_json[\u0027authentication\u0027][\u0027token\u0027] \u003d {\u0027id\u0027: \u0027whocares\u0027}"},{"line_number":186,"context_line":"        self.assertRaises(exception.ValidationError,"},{"line_number":187,"context_line":"                          auth.controllers.AuthInfo,"},{"line_number":188,"context_line":"                          None,"}],"source_content_type":"text/x-python","patch_set":6,"id":"AAAAM3%2F%2B6UE%3D","line":185,"updated":"2013-02-14 18:09:34.000000000","message":"whocares -\u003e uuid","commit_id":"5daf44090947d04c3d330a1aed07cdbf3d57e762"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"c0fd66948f15b497620658195a357ad3b672df21","unresolved":false,"context_lines":[{"line_number":22,"context_line":"from keystone import exception"},{"line_number":23,"context_line":"from keystone.openstack.common import timeutils"},{"line_number":24,"context_line":"from keystone import test"},{"line_number":25,"context_line":""},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"CONF \u003d config.CONF"},{"line_number":28,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2Bz4g%3D","line":25,"updated":"2013-02-18 22:33:21.000000000","message":"we generally do relative imports after keystone package imports\n\n  import test_v3","commit_id":"a33dd427322b85e7a883e19e260539f60e4accad"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"c0fd66948f15b497620658195a357ad3b672df21","unresolved":false,"context_lines":[{"line_number":30,"context_line":"def _build_auth_scope(project_id\u003dNone, project_name\u003dNone,"},{"line_number":31,"context_line":"                      project_domain_id\u003dNone, project_domain_name\u003dNone,"},{"line_number":32,"context_line":"                      domain_id\u003dNone, domain_name\u003dNone):"},{"line_number":33,"context_line":"    scope_json \u003d {}"},{"line_number":34,"context_line":"    if project_id or project_name:"},{"line_number":35,"context_line":"        scope_json[\u0027project\u0027] \u003d {}"},{"line_number":36,"context_line":"        if project_id:"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2Bz4o%3D","line":33,"updated":"2013-02-18 22:33:21.000000000","message":"all the _json suffixes on variable names throughout this file seem very superfluous and almost inaccurate, considering they\u0027re not json yet","commit_id":"a33dd427322b85e7a883e19e260539f60e4accad"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"9579e8fcbf9c7eb671555ecbcca057ff5cfa0b7d","unresolved":false,"context_lines":[{"line_number":75,"context_line":"    return {\u0027id\u0027: token}"},{"line_number":76,"context_line":""},{"line_number":77,"context_line":""},{"line_number":78,"context_line":"def _build_user_auth(token\u003dNone, user_id\u003dNone, username\u003dNone,"},{"line_number":79,"context_line":"                     user_domain_id\u003dNone, user_domain_name\u003dNone,"},{"line_number":80,"context_line":"                     password\u003dNone, project_id\u003dNone, project_name\u003dNone,"},{"line_number":81,"context_line":"                     project_domain_id\u003dNone, project_domain_name\u003dNone,"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2Bz5k%3D","line":78,"updated":"2013-02-18 19:41:18.000000000","message":"_build_request or something? this reads like methods\u003d[\u0027user\u0027] after reading the functions above","commit_id":"a33dd427322b85e7a883e19e260539f60e4accad"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"c0fd66948f15b497620658195a357ad3b672df21","unresolved":false,"context_lines":[{"line_number":145,"context_line":"        auth.controllers.AUTH_METHODS \u003d {}"},{"line_number":146,"context_line":""},{"line_number":147,"context_line":"    def assert_unscoped_token(self, token):"},{"line_number":148,"context_line":"        self.assertEqual([], token[\u0027user\u0027][\u0027roles\u0027])"},{"line_number":149,"context_line":"        self.assertEqual(self.user_id, token[\u0027user\u0027][\u0027id\u0027])"},{"line_number":150,"context_line":""},{"line_number":151,"context_line":"    def assert_scoped_token(self, token):"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2Bz4Q%3D","line":148,"updated":"2013-02-18 22:33:21.000000000","message":"token[\u0027roles\u0027] according to spec","commit_id":"a33dd427322b85e7a883e19e260539f60e4accad"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"9579e8fcbf9c7eb671555ecbcca057ff5cfa0b7d","unresolved":false,"context_lines":[{"line_number":297,"context_line":""},{"line_number":298,"context_line":"class TestAuth(AuthTest):"},{"line_number":299,"context_line":"    def test_unscope_token_with_name(self):"},{"line_number":300,"context_line":"        auth_json \u003d _build_user_auth(token\u003dNone, user_id\u003dNone,"},{"line_number":301,"context_line":"                                     username\u003dself.user_name,"},{"line_number":302,"context_line":"                                     user_domain_id\u003dself.domain_id,"},{"line_number":303,"context_line":"                                     user_domain_name\u003dNone,"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2Bz%2Fc%3D","line":300,"updated":"2013-02-18 19:41:18.000000000","message":"don\u0027t pass all the extra attributes as None, they should be defaulting to None -- makes these tests really hard to read","commit_id":"a33dd427322b85e7a883e19e260539f60e4accad"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"15d2d3a5561540b36b308f14cb70be1fbe01ebe4","unresolved":false,"context_lines":[{"line_number":308,"context_line":"                                     project_domain_name\u003dNone,"},{"line_number":309,"context_line":"                                     domain_id\u003dNone,"},{"line_number":310,"context_line":"                                     domain_name\u003dNone)"},{"line_number":311,"context_line":"        resp \u003d self.post(\u0027/auth\u0027, body\u003dauth_json)"},{"line_number":312,"context_line":"        self.assert_unscoped_token(resp.body)"},{"line_number":313,"context_line":""},{"line_number":314,"context_line":"    def test_project_scope_token_with_name(self):"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2B0H8%3D","line":311,"updated":"2013-02-18 18:24:33.000000000","message":"You may want to look at RestfulTestCase in test_v3.py (that AuthTest is based on) and how it issues these requests - I think it always puts a faked ADMIN token in the request...is that by-passing some functionality that we are therfore not testing?","commit_id":"a33dd427322b85e7a883e19e260539f60e4accad"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"9579e8fcbf9c7eb671555ecbcca057ff5cfa0b7d","unresolved":false,"context_lines":[{"line_number":308,"context_line":"                                     project_domain_name\u003dNone,"},{"line_number":309,"context_line":"                                     domain_id\u003dNone,"},{"line_number":310,"context_line":"                                     domain_name\u003dNone)"},{"line_number":311,"context_line":"        resp \u003d self.post(\u0027/auth\u0027, body\u003dauth_json)"},{"line_number":312,"context_line":"        self.assert_unscoped_token(resp.body)"},{"line_number":313,"context_line":""},{"line_number":314,"context_line":"    def test_project_scope_token_with_name(self):"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2Bz%2Fo%3D","line":311,"in_reply_to":"AAAAM3%2F%2B0H8%3D","updated":"2013-02-18 19:41:18.000000000","message":"yes, it\u0027s bypassing auth \u0026 policy engine -- should be fixed as part of this patch","commit_id":"a33dd427322b85e7a883e19e260539f60e4accad"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"00c2e2e84f8e5627a0e00e99a687f5f355f4f030","unresolved":false,"context_lines":[{"line_number":308,"context_line":"                                     project_domain_name\u003dNone,"},{"line_number":309,"context_line":"                                     domain_id\u003dNone,"},{"line_number":310,"context_line":"                                     domain_name\u003dNone)"},{"line_number":311,"context_line":"        resp \u003d self.post(\u0027/auth\u0027, body\u003dauth_json)"},{"line_number":312,"context_line":"        self.assert_unscoped_token(resp.body)"},{"line_number":313,"context_line":""},{"line_number":314,"context_line":"    def test_project_scope_token_with_name(self):"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAM3%2F%2Bzpo%3D","line":311,"in_reply_to":"AAAAM3%2F%2Bz%2Fo%3D","updated":"2013-02-18 22:19:36.000000000","message":"There\u0027s something wrong with the current test classes. test_v3_identity tests all required admin privilege. Which means we have to use the \u0027ADMIN\u0027 token. Others merely need the scoped token.","commit_id":"a33dd427322b85e7a883e19e260539f60e4accad"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"75e185960b3a2585a2b7c49f2d84b38e16c2df25","unresolved":false,"context_lines":[{"line_number":106,"context_line":""},{"line_number":107,"context_line":"class AuthTest(test_v3.RestfulTestCase):"},{"line_number":108,"context_line":"    def assertUnscopedToken(self, token):"},{"line_number":109,"context_line":"        self.assertEqual([], token[\u0027roles\u0027])"},{"line_number":110,"context_line":"        self.assertEqual(self.user[\u0027id\u0027], token[\u0027user\u0027][\u0027id\u0027])"},{"line_number":111,"context_line":""},{"line_number":112,"context_line":"    def assertScopedToken(self, token):"}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAAM3%2F%2BuEg%3D","line":109,"updated":"2013-02-20 19:27:56.000000000","message":"an unscoped token shouldn\u0027t have a roles element\n\n  self.assertNotIn(\u0027roles\u0027, token)","commit_id":"974c943932d2164062497529a12a7fdeb9e93ee2"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"75e185960b3a2585a2b7c49f2d84b38e16c2df25","unresolved":false,"context_lines":[{"line_number":107,"context_line":"class AuthTest(test_v3.RestfulTestCase):"},{"line_number":108,"context_line":"    def assertUnscopedToken(self, token):"},{"line_number":109,"context_line":"        self.assertEqual([], token[\u0027roles\u0027])"},{"line_number":110,"context_line":"        self.assertEqual(self.user[\u0027id\u0027], token[\u0027user\u0027][\u0027id\u0027])"},{"line_number":111,"context_line":""},{"line_number":112,"context_line":"    def assertScopedToken(self, token):"},{"line_number":113,"context_line":"        self.assertNotEqual([], token[\u0027roles\u0027])"}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAAM3%2F%2BuEY%3D","line":110,"updated":"2013-02-20 19:27:56.000000000","message":"also test for user name\n\nunscoped tokens should also have an \u0027expires\u0027 attribute","commit_id":"974c943932d2164062497529a12a7fdeb9e93ee2"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"75e185960b3a2585a2b7c49f2d84b38e16c2df25","unresolved":false,"context_lines":[{"line_number":110,"context_line":"        self.assertEqual(self.user[\u0027id\u0027], token[\u0027user\u0027][\u0027id\u0027])"},{"line_number":111,"context_line":""},{"line_number":112,"context_line":"    def assertScopedToken(self, token):"},{"line_number":113,"context_line":"        self.assertNotEqual([], token[\u0027roles\u0027])"},{"line_number":114,"context_line":"        self.assertEqual(self.user[\u0027id\u0027], token[\u0027user\u0027][\u0027id\u0027])"},{"line_number":115,"context_line":"        self.assertEqual(self.role_id, token[\u0027roles\u0027][0][\u0027id\u0027])"},{"line_number":116,"context_line":""}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAAM3%2F%2BuEE%3D","line":113,"updated":"2013-02-20 19:27:56.000000000","message":"assertTrue(token[\u0027roles\u0027])\n\nand then iterates the roles and make sure they all have an id and name","commit_id":"974c943932d2164062497529a12a7fdeb9e93ee2"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"75e185960b3a2585a2b7c49f2d84b38e16c2df25","unresolved":false,"context_lines":[{"line_number":111,"context_line":""},{"line_number":112,"context_line":"    def assertScopedToken(self, token):"},{"line_number":113,"context_line":"        self.assertNotEqual([], token[\u0027roles\u0027])"},{"line_number":114,"context_line":"        self.assertEqual(self.user[\u0027id\u0027], token[\u0027user\u0027][\u0027id\u0027])"},{"line_number":115,"context_line":"        self.assertEqual(self.role_id, token[\u0027roles\u0027][0][\u0027id\u0027])"},{"line_number":116,"context_line":""},{"line_number":117,"context_line":"    def assertValidErrorResponse(self, r):"}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAAM3%2F%2BuD8%3D","line":114,"updated":"2013-02-20 19:27:56.000000000","message":"check for a name","commit_id":"974c943932d2164062497529a12a7fdeb9e93ee2"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"75e185960b3a2585a2b7c49f2d84b38e16c2df25","unresolved":false,"context_lines":[{"line_number":112,"context_line":"    def assertScopedToken(self, token):"},{"line_number":113,"context_line":"        self.assertNotEqual([], token[\u0027roles\u0027])"},{"line_number":114,"context_line":"        self.assertEqual(self.user[\u0027id\u0027], token[\u0027user\u0027][\u0027id\u0027])"},{"line_number":115,"context_line":"        self.assertEqual(self.role_id, token[\u0027roles\u0027][0][\u0027id\u0027])"},{"line_number":116,"context_line":""},{"line_number":117,"context_line":"    def assertValidErrorResponse(self, r):"},{"line_number":118,"context_line":"        pass"}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAAM3%2F%2BuDs%3D","line":115,"updated":"2013-02-20 19:27:56.000000000","message":"also need to test for a catalog, which i haven\u0027t seen any tests producing, and methods\n\nalso need to test the structure of included project and domain element, so i would suggest creating assertProjectScopedToken and assertDomainScopedToken methods that call this one for things in common","commit_id":"974c943932d2164062497529a12a7fdeb9e93ee2"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"75e185960b3a2585a2b7c49f2d84b38e16c2df25","unresolved":false,"context_lines":[{"line_number":115,"context_line":"        self.assertEqual(self.role_id, token[\u0027roles\u0027][0][\u0027id\u0027])"},{"line_number":116,"context_line":""},{"line_number":117,"context_line":"    def assertValidErrorResponse(self, r):"},{"line_number":118,"context_line":"        pass"},{"line_number":119,"context_line":""},{"line_number":120,"context_line":"    def assertEqualTokens(self, a, b):"},{"line_number":121,"context_line":"        \"\"\"Assert that two tokens are equal."}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAAM3%2F%2BuDU%3D","line":118,"updated":"2013-02-20 19:27:56.000000000","message":"please don\u0027t suppress test failures","commit_id":"974c943932d2164062497529a12a7fdeb9e93ee2"}],"tests/test_v3_identity.py":[{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"0553a159339c25a6fdb847522d44158c9f6aad8c","unresolved":false,"context_lines":[{"line_number":203,"context_line":""},{"line_number":204,"context_line":"        # check that the project and user are still enabled"},{"line_number":205,"context_line":"        # FIXME(gyee): are these tests still valid since user should not"},{"line_number":206,"context_line":"        # be able to authenticate into a disabled domain"},{"line_number":207,"context_line":"        #r \u003d self.get(\u0027/projects/%(project_id)s\u0027 % {"},{"line_number":208,"context_line":"        #    \u0027project_id\u0027: self.project_id})"},{"line_number":209,"context_line":"        #self.assertValidProjectResponse(r, self.project)"}],"source_content_type":"text/x-python","patch_set":20,"id":"AAAAM3%2F%2BuU4%3D","line":206,"updated":"2013-02-20 18:05:33.000000000","message":"my fix for this was to keep the test as is, but create a domain within the test to disable... and then use the original (now failing) test to assert that you can\u0027t login if your domain is disabled :)","commit_id":"466157fb553580f59f15893642bbae573257b7c2"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"0553a159339c25a6fdb847522d44158c9f6aad8c","unresolved":false,"context_lines":[{"line_number":449,"context_line":"        self.assertIn(collection_url, r.body[\u0027links\u0027][\u0027self\u0027])"},{"line_number":450,"context_line":""},{"line_number":451,"context_line":"        # FIXME(gyee): this test is no longer valid as user"},{"line_number":452,"context_line":"        # have no role in the project. Can\u0027t get a scoped token"},{"line_number":453,"context_line":"        #self.delete(member_url)"},{"line_number":454,"context_line":"        #r \u003d self.get(collection_url)"},{"line_number":455,"context_line":"        #self.assertValidRoleListResponse(r, expected_length\u003d0)"}],"source_content_type":"text/x-python","patch_set":20,"id":"AAAAM3%2F%2BuU0%3D","line":452,"updated":"2013-02-20 18:05:33.000000000","message":"same as above","commit_id":"466157fb553580f59f15893642bbae573257b7c2"}],"tools/pip-requires":[{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"a0a31442d0cc3f05c8b679e4e59ae260df1182f6","unresolved":false,"context_lines":[{"line_number":12,"context_line":"lxml"},{"line_number":13,"context_line":"iso8601\u003e\u003d0.1.4"},{"line_number":14,"context_line":"python-keystoneclient\u003e\u003d0.2,\u003c0.3"},{"line_number":15,"context_line":"#http://tarballs.openstack.org/oslo-config/oslo-config-2013.1b3.tar.gz#egg\u003doslo-config"}],"source_content_type":"application/octet-stream","patch_set":14,"id":"AAAAM3%2F%2Bwg8%3D","line":15,"updated":"2013-02-19 21:00:33.000000000","message":"-1","commit_id":"2823e852c387292387ce35087af92491ac11b472"}]}
