)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"380a37edfb05107181382c047fe903c320718d5d","unresolved":false,"context_lines":[{"line_number":9,"context_line":"Ironic API already enforces admin role to run node-show. So a new"},{"line_number":10,"context_line":"policy mask_password is added to control if plain text passwords"},{"line_number":11,"context_line":"in driver_info should be masked before sending back to API call."},{"line_number":12,"context_line":"The default is to only not mask for user admin on tenant admin."},{"line_number":13,"context_line":""},{"line_number":14,"context_line":"Change-Id: Icd3e6be049376bf7b4468f0c149a72a06643da32"},{"line_number":15,"context_line":"Closes-Bug: #1406191"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":7,"id":"da86d52c_725b7387","line":12,"updated":"2015-02-03 10:04:53.000000000","message":"This is actually not true right? It\u0027s masking for everyone now","commit_id":"a09b8b6c254d44f18f022e0b8f16cb812e806a99"}],"etc/ironic/ironic.conf.sample":[{"author":{"_account_id":2889,"name":"Aeva Black","email":"aeva.online@gmail.com","username":"tenbrae"},"change_message_id":"71cd9ceda1e2d03b9887dcef4524ac4c483aa136","unresolved":false,"context_lines":[{"line_number":504,"context_line":"# from a collection resource. (integer value)"},{"line_number":505,"context_line":"#max_limit\u003d1000"},{"line_number":506,"context_line":""},{"line_number":507,"context_line":"# Mask password from driver_info in repsonse"},{"line_number":508,"context_line":"#mask_password\u003dFalse"},{"line_number":509,"context_line":""},{"line_number":510,"context_line":"[conductor]"}],"source_content_type":"application/octet-stream","patch_set":1,"id":"fa81d914_ffda12e8","line":507,"updated":"2015-01-28 06:08:00.000000000","message":"This help string is not consistent with the actual help string.\nPlease use tools/config/generate_sample.sh to regenerate this file.","commit_id":"1a075a2e5f88fe9f28db43b782b881b9c119ca5a"},{"author":{"_account_id":4992,"name":"malini-k-bhandaru","email":"malini.k.bhandaru@intel.com","username":"malini-k-bhandaru"},"change_message_id":"84c3dd1ad890d9480ca865c2ceba8b4a0a686f7a","unresolved":false,"context_lines":[{"line_number":504,"context_line":"# from a collection resource. (integer value)"},{"line_number":505,"context_line":"#max_limit\u003d1000"},{"line_number":506,"context_line":""},{"line_number":507,"context_line":"# Mask password from driver_info in repsonse"},{"line_number":508,"context_line":"#mask_password\u003dFalse"},{"line_number":509,"context_line":""},{"line_number":510,"context_line":"[conductor]"}],"source_content_type":"application/octet-stream","patch_set":1,"id":"fa81d914_18e45c0c","line":507,"updated":"2015-01-28 07:55:53.000000000","message":"s/repsonse/response","commit_id":"1a075a2e5f88fe9f28db43b782b881b9c119ca5a"},{"author":{"_account_id":13790,"name":"Zhenzan Zhou","email":"linuxosa@gmail.com","username":"zhenzanzhou"},"change_message_id":"6d5896776ce2550c5d0dc48ff9939d16d658d212","unresolved":false,"context_lines":[{"line_number":504,"context_line":"# from a collection resource. (integer value)"},{"line_number":505,"context_line":"#max_limit\u003d1000"},{"line_number":506,"context_line":""},{"line_number":507,"context_line":"# Mask password from driver_info in repsonse"},{"line_number":508,"context_line":"#mask_password\u003dFalse"},{"line_number":509,"context_line":""},{"line_number":510,"context_line":"[conductor]"}],"source_content_type":"application/octet-stream","patch_set":1,"id":"fa81d914_aeddc644","line":507,"in_reply_to":"fa81d914_ffda12e8","updated":"2015-01-28 08:45:21.000000000","message":"Ah, I\u0027m not aware of this tool, thanks a lot.","commit_id":"1a075a2e5f88fe9f28db43b782b881b9c119ca5a"}],"etc/ironic/policy.json":[{"author":{"_account_id":10343,"name":"Jim Rollenhagen","email":"jim@jimrollenhagen.com","username":"jimrollenhagen"},"change_message_id":"ec80052ecf1411f3aa476efb56704465edfc5971","unresolved":false,"context_lines":[{"line_number":1,"context_line":"{"},{"line_number":2,"context_line":"    \"admin_api\": \"role:admin or role:administrator\","},{"line_number":3,"context_line":"    \"mask_password\": \"not (tenant:admin and user:admin)\","},{"line_number":4,"context_line":"    \"default\": \"rule:admin_api\""},{"line_number":5,"context_line":"}"}],"source_content_type":"application/json","patch_set":6,"id":"da86d52c_ce03a1b6","line":3,"updated":"2015-02-03 03:53:54.000000000","message":"If I\u0027m not mistaken, user:admin means that the user ID (username?), as defined by the X-User or X-User-ID header, is equal to admin. This is fine for devstack, but I\u0027m wondering how many clouds have a user named \"admin\". Same for tenant:admin, I guess.\n\nIs this ok? Do we reasonably expect deployers to be required to change this file? What if \"admin\" is not actually the admin user, but some user with lower privilege?\n\nMaybe we should just default this to \"True\" to indicate that if a deployer wants users to see passwords, they need to explicitly declare which users can do that. Would this break devstack? (I doubt it)\n\nThoughts?","commit_id":"f64419d72be5411f3dde738e60f2f81254154d6d"},{"author":{"_account_id":10343,"name":"Jim Rollenhagen","email":"jim@jimrollenhagen.com","username":"jimrollenhagen"},"change_message_id":"245f3a2ea6ef018aebdb3369e246984b42a4ef26","unresolved":false,"context_lines":[{"line_number":1,"context_line":"{"},{"line_number":2,"context_line":"    \"admin_api\": \"role:admin or role:administrator\","},{"line_number":3,"context_line":"    \"mask_password\": \"not (tenant:admin and user:admin)\","},{"line_number":4,"context_line":"    \"default\": \"rule:admin_api\""},{"line_number":5,"context_line":"}"}],"source_content_type":"application/json","patch_set":6,"id":"da86d52c_2e999d1f","line":3,"in_reply_to":"da86d52c_ce03a1b6","updated":"2015-02-03 04:07:48.000000000","message":"FWIW, I just ran this in devstack and it is indeed dependent on the username.","commit_id":"f64419d72be5411f3dde738e60f2f81254154d6d"},{"author":{"_account_id":13790,"name":"Zhenzan Zhou","email":"linuxosa@gmail.com","username":"zhenzanzhou"},"change_message_id":"9d66468f15707eece32ae1ad07bc9e9ed343a148","unresolved":false,"context_lines":[{"line_number":1,"context_line":"{"},{"line_number":2,"context_line":"    \"admin_api\": \"role:admin or role:administrator\","},{"line_number":3,"context_line":"    \"mask_password\": \"not (tenant:admin and user:admin)\","},{"line_number":4,"context_line":"    \"default\": \"rule:admin_api\""},{"line_number":5,"context_line":"}"}],"source_content_type":"application/json","patch_set":6,"id":"da86d52c_74028870","line":3,"in_reply_to":"da86d52c_ce03a1b6","updated":"2015-02-03 05:59:13.000000000","message":"Yes, \u0027user\u0027 is defined by X-User or X-User-ID in hooks.py. I think your concern is reasonable. We can set it to \u0027@\u0027 which means True for everything. Thanks.","commit_id":"f64419d72be5411f3dde738e60f2f81254154d6d"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"f3fcb17dfd398120406a6a3e2f784cd2b35becd5","unresolved":false,"context_lines":[{"line_number":1,"context_line":"{"},{"line_number":2,"context_line":"    \"admin_api\": \"role:admin or role:administrator\","},{"line_number":3,"context_line":"    \"mask_password\": \"@\","},{"line_number":4,"context_line":"    \"default\": \"rule:admin_api\""},{"line_number":5,"context_line":"}"}],"source_content_type":"application/json","patch_set":8,"id":"da86d52c_3fda7fe8","line":3,"updated":"2015-02-03 22:35:10.000000000","message":"This translates to \u0027mask passwords for everyone\u0027\n\nand to allow it for eg admin, we\u0027d need to do something like \"not rule:admin_api\"\n\nWould it be easier to understand if it was the reverse:\n\"show_passwords\": \"!\"   -- \"show passwords to no one\"\n\nallowing for admins could be \"show_passwords\": \"rule:admin_api\"","commit_id":"7502f77303837368a2907081f261cedb6e1d9bc2"}],"ironic/api/controllers/v1/node.py":[{"author":{"_account_id":2889,"name":"Aeva Black","email":"aeva.online@gmail.com","username":"tenbrae"},"change_message_id":"71cd9ceda1e2d03b9887dcef4524ac4c483aa136","unresolved":false,"context_lines":[{"line_number":858,"context_line":"                                **node.as_dict())"},{"line_number":859,"context_line":"        new_node.create()"},{"line_number":860,"context_line":"        # Set the HTTP Location Header"},{"line_number":861,"context_line":"        pecan.response.location \u003d link.build_url(\u0027nodes\u0027, new_node.uuid)"},{"line_number":862,"context_line":"        return Node.convert_with_links(new_node)"},{"line_number":863,"context_line":""},{"line_number":864,"context_line":"    @wsme.validate(types.uuid, [NodePatchType])"}],"source_content_type":"text/x-python","patch_set":1,"id":"fa81d914_bfd17acf","line":861,"updated":"2015-01-28 06:08:00.000000000","message":"Even though the node was just created, you should mask the password in the return here","commit_id":"1a075a2e5f88fe9f28db43b782b881b9c119ca5a"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"190b2eb9e9e75b5ee2f4ab7ed5d7cf027431d68e","unresolved":false,"context_lines":[{"line_number":858,"context_line":"                                **node.as_dict())"},{"line_number":859,"context_line":"        new_node.create()"},{"line_number":860,"context_line":"        # Set the HTTP Location Header"},{"line_number":861,"context_line":"        pecan.response.location \u003d link.build_url(\u0027nodes\u0027, new_node.uuid)"},{"line_number":862,"context_line":"        return Node.convert_with_links(new_node)"},{"line_number":863,"context_line":""},{"line_number":864,"context_line":"    @wsme.validate(types.uuid, [NodePatchType])"}],"source_content_type":"text/x-python","patch_set":1,"id":"fa81d914_cfa671c1","line":861,"in_reply_to":"fa81d914_0ecb3273","updated":"2015-01-28 11:52:38.000000000","message":"Hi Zehnzan,\n\nIs that really needed? I mean user could just check the request made. Also our API let him validate() or even try to power on/off a node to checks whether the username/password is working.\n\nI think we could mask every time we return from the API. See also my comment at L924 about doing it in the convert_with_links() method.","commit_id":"1a075a2e5f88fe9f28db43b782b881b9c119ca5a"},{"author":{"_account_id":13790,"name":"Zhenzan Zhou","email":"linuxosa@gmail.com","username":"zhenzanzhou"},"change_message_id":"6d5896776ce2550c5d0dc48ff9939d16d658d212","unresolved":false,"context_lines":[{"line_number":858,"context_line":"                                **node.as_dict())"},{"line_number":859,"context_line":"        new_node.create()"},{"line_number":860,"context_line":"        # Set the HTTP Location Header"},{"line_number":861,"context_line":"        pecan.response.location \u003d link.build_url(\u0027nodes\u0027, new_node.uuid)"},{"line_number":862,"context_line":"        return Node.convert_with_links(new_node)"},{"line_number":863,"context_line":""},{"line_number":864,"context_line":"    @wsme.validate(types.uuid, [NodePatchType])"}],"source_content_type":"text/x-python","patch_set":1,"id":"fa81d914_0ecb3273","line":861,"in_reply_to":"fa81d914_bfd17acf","updated":"2015-01-28 08:45:21.000000000","message":"Maybe we don\u0027t mask it here so user has a chance to confirm he has typed the correct password? \nBut \u0027node-list --detail\u0027 should be masked.","commit_id":"1a075a2e5f88fe9f28db43b782b881b9c119ca5a"},{"author":{"_account_id":13790,"name":"Zhenzan Zhou","email":"linuxosa@gmail.com","username":"zhenzanzhou"},"change_message_id":"fcf92457f590c59064efb6bfc761a333ce18508f","unresolved":false,"context_lines":[{"line_number":858,"context_line":"                                **node.as_dict())"},{"line_number":859,"context_line":"        new_node.create()"},{"line_number":860,"context_line":"        # Set the HTTP Location Header"},{"line_number":861,"context_line":"        pecan.response.location \u003d link.build_url(\u0027nodes\u0027, new_node.uuid)"},{"line_number":862,"context_line":"        return Node.convert_with_links(new_node)"},{"line_number":863,"context_line":""},{"line_number":864,"context_line":"    @wsme.validate(types.uuid, [NodePatchType])"}],"source_content_type":"text/x-python","patch_set":1,"id":"fa81d914_9a73d94c","line":861,"in_reply_to":"fa81d914_cfa671c1","updated":"2015-01-28 12:19:31.000000000","message":"Sounds reasonable to use validate(). Thanks.","commit_id":"1a075a2e5f88fe9f28db43b782b881b9c119ca5a"},{"author":{"_account_id":2889,"name":"Aeva Black","email":"aeva.online@gmail.com","username":"tenbrae"},"change_message_id":"71cd9ceda1e2d03b9887dcef4524ac4c483aa136","unresolved":false,"context_lines":[{"line_number":920,"context_line":""},{"line_number":921,"context_line":"        new_node \u003d pecan.request.rpcapi.update_node("},{"line_number":922,"context_line":"                         pecan.request.context, rpc_node, topic)"},{"line_number":923,"context_line":""},{"line_number":924,"context_line":"        return Node.convert_with_links(new_node)"},{"line_number":925,"context_line":""},{"line_number":926,"context_line":"    @wsme_pecan.wsexpose(None, types.uuid, status_code\u003d204)"}],"source_content_type":"text/x-python","patch_set":1,"id":"fa81d914_dfd62ec5","line":923,"updated":"2015-01-28 06:08:00.000000000","message":"You need to mask_password here as well","commit_id":"1a075a2e5f88fe9f28db43b782b881b9c119ca5a"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"190b2eb9e9e75b5ee2f4ab7ed5d7cf027431d68e","unresolved":false,"context_lines":[{"line_number":921,"context_line":"        new_node \u003d pecan.request.rpcapi.update_node("},{"line_number":922,"context_line":"                         pecan.request.context, rpc_node, topic)"},{"line_number":923,"context_line":""},{"line_number":924,"context_line":"        return Node.convert_with_links(new_node)"},{"line_number":925,"context_line":""},{"line_number":926,"context_line":"    @wsme_pecan.wsexpose(None, types.uuid, status_code\u003d204)"},{"line_number":927,"context_line":"    def delete(self, node_uuid):"}],"source_content_type":"text/x-python","patch_set":1,"id":"fa81d914_efddf543","line":924,"updated":"2015-01-28 11:52:38.000000000","message":"The method convert_with_links() from the Node class converts all the nodes before returning as an API response. What you think about masking the password there?","commit_id":"1a075a2e5f88fe9f28db43b782b881b9c119ca5a"},{"author":{"_account_id":13790,"name":"Zhenzan Zhou","email":"linuxosa@gmail.com","username":"zhenzanzhou"},"change_message_id":"fcf92457f590c59064efb6bfc761a333ce18508f","unresolved":false,"context_lines":[{"line_number":921,"context_line":"        new_node \u003d pecan.request.rpcapi.update_node("},{"line_number":922,"context_line":"                         pecan.request.context, rpc_node, topic)"},{"line_number":923,"context_line":""},{"line_number":924,"context_line":"        return Node.convert_with_links(new_node)"},{"line_number":925,"context_line":""},{"line_number":926,"context_line":"    @wsme_pecan.wsexpose(None, types.uuid, status_code\u003d204)"},{"line_number":927,"context_line":"    def delete(self, node_uuid):"}],"source_content_type":"text/x-python","patch_set":1,"id":"fa81d914_baa17dab","line":924,"in_reply_to":"fa81d914_efddf543","updated":"2015-01-28 12:19:31.000000000","message":"Yes, we have got the same idea:-) Thanks.","commit_id":"1a075a2e5f88fe9f28db43b782b881b9c119ca5a"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"8696f41048abded93451306af05e1045f21688e4","unresolved":false,"context_lines":[{"line_number":523,"context_line":"    def convert_with_links(cls, rpc_node, expand\u003dTrue):"},{"line_number":524,"context_line":"        # TODO(zhenzanz): Find a better place to enforce \u0027mask_password\u0027"},{"line_number":525,"context_line":"        creds \u003d pecan.request.context.to_dict()"},{"line_number":526,"context_line":"        mask_password \u003d policy.enforce(\u0027mask_password\u0027, creds, creds)"},{"line_number":527,"context_line":"        if mask_password:"},{"line_number":528,"context_line":"            rpc_node[\u0027driver_info\u0027] \u003d strutils.mask_password("},{"line_number":529,"context_line":"                                               rpc_node[\u0027driver_info\u0027],"}],"source_content_type":"text/x-python","patch_set":3,"id":"fa81d914_8b6cff36","line":526,"updated":"2015-01-30 10:41:41.000000000","message":"I think this should go to the context object, like we have for is_public_api, is_admin etc... The policy enforcement happens there.\n\nSo, first it should go to the ContextHook we have in pecan, see[1]. There you can determine whether the passwords should be masked or not and passed down to as part of the creation of the RequestContext object[2]. So mask_password can be an attribute of the object and also should be returned as part of the to_dict() method.\n\nSo here you simple do:\n\n if pecan.request.context.mask_password:\n     ... strutils.mask_password(...)\n\nThis also makes it simpler to access the policy from other places, like if we start masking passwords from other resources -- Not needed now, but potentially we could store passwords in the Chassis resources for e.g.\n\n [1] https://github.com/openstack/ironic/blob/master/ironic/api/hooks.py#L82-L84\n [2] https://github.com/openstack/ironic/blob/master/ironic/common/context.py","commit_id":"f07b57bd1cb741656eddeb1ce018e373ce97e9ff"},{"author":{"_account_id":10343,"name":"Jim Rollenhagen","email":"jim@jimrollenhagen.com","username":"jimrollenhagen"},"change_message_id":"b2927804ebb90aa7b833db6f8bb91809338d4cd9","unresolved":false,"context_lines":[{"line_number":520,"context_line":""},{"line_number":521,"context_line":"    @classmethod"},{"line_number":522,"context_line":"    def convert_with_links(cls, rpc_node, expand\u003dTrue):"},{"line_number":523,"context_line":"        # TODO(zhenzanz): Find a better place to enforce \u0027mask_password\u0027"},{"line_number":524,"context_line":"        if pecan.request.context.mask_password:"},{"line_number":525,"context_line":"            rpc_node[\u0027driver_info\u0027] \u003d strutils.mask_password("},{"line_number":526,"context_line":"                                               rpc_node[\u0027driver_info\u0027],"}],"source_content_type":"text/x-python","patch_set":4,"id":"fa81d914_fd89bd75","line":523,"updated":"2015-01-30 14:52:05.000000000","message":"This location seems fine to me, can we remove this TODO?","commit_id":"f18160b3535a3b1a40aa103ed2fdf62dbb1be03a"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"82f2f82f46df8e17bada17d74fa86680e49b09d4","unresolved":false,"context_lines":[{"line_number":520,"context_line":""},{"line_number":521,"context_line":"    @classmethod"},{"line_number":522,"context_line":"    def convert_with_links(cls, rpc_node, expand\u003dTrue):"},{"line_number":523,"context_line":"        # TODO(zhenzanz): Find a better place to enforce \u0027mask_password\u0027"},{"line_number":524,"context_line":"        if pecan.request.context.mask_password:"},{"line_number":525,"context_line":"            rpc_node[\u0027driver_info\u0027] \u003d strutils.mask_password("},{"line_number":526,"context_line":"                                               rpc_node[\u0027driver_info\u0027],"}],"source_content_type":"text/x-python","patch_set":4,"id":"fa81d914_1d5771cb","line":523,"updated":"2015-01-30 14:55:15.000000000","message":"this TODO can be removed I believe","commit_id":"f18160b3535a3b1a40aa103ed2fdf62dbb1be03a"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"f3fcb17dfd398120406a6a3e2f784cd2b35becd5","unresolved":false,"context_lines":[{"line_number":531,"context_line":"        if pecan.request.context.mask_password:"},{"line_number":532,"context_line":"            rpc_node[\u0027driver_info\u0027] \u003d strutils.mask_password("},{"line_number":533,"context_line":"                                               rpc_node[\u0027driver_info\u0027],"},{"line_number":534,"context_line":"                                               \"******\")"},{"line_number":535,"context_line":"        node \u003d Node(**rpc_node.as_dict())"},{"line_number":536,"context_line":"        assert_juno_provision_state_name(node)"},{"line_number":537,"context_line":"        return cls._convert_with_links(node, pecan.request.host_url,"}],"source_content_type":"text/x-python","patch_set":8,"id":"da86d52c_df1ec35e","line":534,"updated":"2015-02-03 22:35:10.000000000","message":"we\u0027re slowly changing the code to s/rpc_node[\u0027driver_info\u0027]/rpc_node.driver_info/\n\nI\u0027ve got a suggestion. What do you think about moving this down to cls._convert_with_links(), for these reasons:\n\n1. this modifies the rpc_node\u0027s driver_info. IF the code that calls this method ever changes to do something with rpc_node after this call, it could cause problems.\n\n2. if expand is False, there is no need to do this because driver_info won\u0027t be shown. (This is an optimization that probably isn\u0027t that important.)\n\nOr leave it in here and make the change to the node (below) instead of to rpc_node.","commit_id":"7502f77303837368a2907081f261cedb6e1d9bc2"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"19339738aebee6cc902f6c6353df8ae086207bfa","unresolved":false,"context_lines":[{"line_number":521,"context_line":"            node.unset_fields_except(except_list)"},{"line_number":522,"context_line":"        else:"},{"line_number":523,"context_line":"            mask_password \u003d pecan.request.context.mask_password"},{"line_number":524,"context_line":"            if mask_password and hasattr(node, \u0027driver_info\u0027):"},{"line_number":525,"context_line":"                setattr(node, \u0027driver_info\u0027,"},{"line_number":526,"context_line":"                        ast.literal_eval(strutils.mask_password("},{"line_number":527,"context_line":"                                                  node.driver_info,"}],"source_content_type":"text/x-python","patch_set":9,"id":"da86d52c_8ac9595b","line":524,"updated":"2015-02-04 09:42:48.000000000","message":"Node always will have the driver_info attribute, it\u0027s set right there at L468.","commit_id":"d725e5bba742645590625c39471a228785248644"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"19339738aebee6cc902f6c6353df8ae086207bfa","unresolved":false,"context_lines":[{"line_number":522,"context_line":"        else:"},{"line_number":523,"context_line":"            mask_password \u003d pecan.request.context.mask_password"},{"line_number":524,"context_line":"            if mask_password and hasattr(node, \u0027driver_info\u0027):"},{"line_number":525,"context_line":"                setattr(node, \u0027driver_info\u0027,"},{"line_number":526,"context_line":"                        ast.literal_eval(strutils.mask_password("},{"line_number":527,"context_line":"                                                  node.driver_info,"},{"line_number":528,"context_line":"                                                  \"******\")))"}],"source_content_type":"text/x-python","patch_set":9,"id":"da86d52c_0a0c89a4","line":525,"updated":"2015-02-04 09:42:48.000000000","message":"setattr() is not needed...\n\n if pecan.request.context.mask_password:\n     node.driver_info \u003d ast.literal_eval(strutils.mask_password(node.driver_info, \"******\"))","commit_id":"d725e5bba742645590625c39471a228785248644"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"19339738aebee6cc902f6c6353df8ae086207bfa","unresolved":false,"context_lines":[{"line_number":525,"context_line":"                setattr(node, \u0027driver_info\u0027,"},{"line_number":526,"context_line":"                        ast.literal_eval(strutils.mask_password("},{"line_number":527,"context_line":"                                                  node.driver_info,"},{"line_number":528,"context_line":"                                                  \"******\")))"},{"line_number":529,"context_line":"            node.ports \u003d [link.Link.make_link(\u0027self\u0027, url, \u0027nodes\u0027,"},{"line_number":530,"context_line":"                                              node.uuid + \"/ports\"),"},{"line_number":531,"context_line":"                          link.Link.make_link(\u0027bookmark\u0027, url, \u0027nodes\u0027,"}],"source_content_type":"text/x-python","patch_set":9,"id":"da86d52c_2a0b0d7e","line":528,"updated":"2015-02-04 09:42:48.000000000","message":"Nothing to change in the patch because of this comment, just a rant...\n\nI just hate the way mask_password() actually works, it gets a dict and returns a string -.-","commit_id":"d725e5bba742645590625c39471a228785248644"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"92f3cbf82b9348162cb80abcf3d04828952c93a0","unresolved":false,"context_lines":[{"line_number":525,"context_line":"                setattr(node, \u0027driver_info\u0027,"},{"line_number":526,"context_line":"                        ast.literal_eval(strutils.mask_password("},{"line_number":527,"context_line":"                                                  node.driver_info,"},{"line_number":528,"context_line":"                                                  \"******\")))"},{"line_number":529,"context_line":"            node.ports \u003d [link.Link.make_link(\u0027self\u0027, url, \u0027nodes\u0027,"},{"line_number":530,"context_line":"                                              node.uuid + \"/ports\"),"},{"line_number":531,"context_line":"                          link.Link.make_link(\u0027bookmark\u0027, url, \u0027nodes\u0027,"}],"source_content_type":"text/x-python","patch_set":9,"id":"da86d52c_df8b0866","line":528,"in_reply_to":"da86d52c_2a0b0d7e","updated":"2015-02-04 15:00:50.000000000","message":"+1. It should return the same type it got, but my guess is that it started off with strings and people started passing other types to it...","commit_id":"d725e5bba742645590625c39471a228785248644"}],"ironic/api/hooks.py":[{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"8696f41048abded93451306af05e1045f21688e4","unresolved":false,"context_lines":[{"line_number":76,"context_line":"            \u0027roles\u0027: headers.get(\u0027X-Roles\u0027, \u0027\u0027).split(\u0027,\u0027),"},{"line_number":77,"context_line":"        }"},{"line_number":78,"context_line":"        return creds"},{"line_number":79,"context_line":""},{"line_number":80,"context_line":"    def before(self, state):"},{"line_number":81,"context_line":"        creds \u003d self._gen_creds(state)"},{"line_number":82,"context_line":"        # NOTE(adam_g): We also check the previous \u0027admin\u0027 rule to ensure"}],"source_content_type":"text/x-python","patch_set":3,"id":"fa81d914_4b7127df","line":79,"updated":"2015-01-30 10:41:41.000000000","message":"This change looks unrelated to the patch.\n\nBut, see my suggestion on node.py. I think the policy enforcement could happen in this hook, like the others.","commit_id":"f07b57bd1cb741656eddeb1ce018e373ce97e9ff"},{"author":{"_account_id":13362,"name":"Tan Lin","email":"lin.tan@intel.com","username":"zero"},"change_message_id":"bb3f7ae1a704c171946f07933ee7644dd8304aa3","unresolved":false,"context_lines":[{"line_number":83,"context_line":"                    policy.enforce(\u0027admin\u0027, creds, creds))"},{"line_number":84,"context_line":"        is_public_api \u003d state.request.environ.get(\u0027is_public_api\u0027, False)"},{"line_number":85,"context_line":"        mask_password \u003d not policy.enforce(\u0027show_password\u0027, creds, creds)"},{"line_number":86,"context_line":""},{"line_number":87,"context_line":"        state.request.context \u003d context.RequestContext("},{"line_number":88,"context_line":"            is_admin\u003dis_admin,"},{"line_number":89,"context_line":"            is_public_api\u003dis_public_api,"}],"source_content_type":"text/x-python","patch_set":9,"id":"da86d52c_6413710d","line":86,"updated":"2015-02-04 14:08:44.000000000","message":"nit: Is it possible to keep consistent with the name of parameter, using show_password for all?","commit_id":"d725e5bba742645590625c39471a228785248644"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"92f3cbf82b9348162cb80abcf3d04828952c93a0","unresolved":false,"context_lines":[{"line_number":83,"context_line":"                    policy.enforce(\u0027admin\u0027, creds, creds))"},{"line_number":84,"context_line":"        is_public_api \u003d state.request.environ.get(\u0027is_public_api\u0027, False)"},{"line_number":85,"context_line":"        mask_password \u003d not policy.enforce(\u0027show_password\u0027, creds, creds)"},{"line_number":86,"context_line":""},{"line_number":87,"context_line":"        state.request.context \u003d context.RequestContext("},{"line_number":88,"context_line":"            is_admin\u003dis_admin,"},{"line_number":89,"context_line":"            is_public_api\u003dis_public_api,"}],"source_content_type":"text/x-python","patch_set":9,"id":"da86d52c_3f25045c","line":86,"in_reply_to":"da86d52c_6413710d","updated":"2015-02-04 15:00:50.000000000","message":"+1 for Tan\u0027s suggestion. But I don\u0027t feel strongly about it. Guess that\u0027s why it is a nit ;)","commit_id":"d725e5bba742645590625c39471a228785248644"}],"ironic/common/context.py":[{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"82f2f82f46df8e17bada17d74fa86680e49b09d4","unresolved":false,"context_lines":[{"line_number":21,"context_line":"    def __init__(self, auth_token\u003dNone, domain_id\u003dNone, domain_name\u003dNone,"},{"line_number":22,"context_line":"                 user\u003dNone, tenant\u003dNone, is_admin\u003dFalse, is_public_api\u003dFalse,"},{"line_number":23,"context_line":"                 read_only\u003dFalse, show_deleted\u003dFalse, request_id\u003dNone,"},{"line_number":24,"context_line":"                 roles\u003dNone, mask_password\u003dTrue):"},{"line_number":25,"context_line":"        \"\"\"Stores several additional request parameters:"},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"        :param domain_id: The ID of the domain."}],"source_content_type":"text/x-python","patch_set":4,"id":"fa81d914_9d01a1b1","line":24,"updated":"2015-01-30 14:55:15.000000000","message":"nit: probably need to be False because the default policy is to not mask it","commit_id":"f18160b3535a3b1a40aa103ed2fdf62dbb1be03a"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"82f2f82f46df8e17bada17d74fa86680e49b09d4","unresolved":false,"context_lines":[{"line_number":56,"context_line":"                \u0027request_id\u0027: self.request_id,"},{"line_number":57,"context_line":"                \u0027domain_id\u0027: self.domain_id,"},{"line_number":58,"context_line":"                \u0027roles\u0027: self.roles,"},{"line_number":59,"context_line":"                \u0027domain_name\u0027: self.domain_name,"},{"line_number":60,"context_line":"                \u0027is_public_api\u0027: self.is_public_api}"},{"line_number":61,"context_line":""},{"line_number":62,"context_line":"    @classmethod"}],"source_content_type":"text/x-python","patch_set":4,"id":"fa81d914_7d714d75","line":59,"updated":"2015-01-30 14:55:15.000000000","message":"\u0027mask_password\u0027: self.mask_password","commit_id":"f18160b3535a3b1a40aa103ed2fdf62dbb1be03a"}],"ironic/tests/api/test_hooks.py":[{"author":{"_account_id":10343,"name":"Jim Rollenhagen","email":"jim@jimrollenhagen.com","username":"jimrollenhagen"},"change_message_id":"b2927804ebb90aa7b833db6f8bb91809338d4cd9","unresolved":false,"context_lines":[{"line_number":243,"context_line":"            domain_id\u003dheaders[\u0027X-User-Domain-Id\u0027],"},{"line_number":244,"context_line":"            domain_name\u003dheaders[\u0027X-User-Domain-Name\u0027],"},{"line_number":245,"context_line":"            is_public_api\u003dFalse,"},{"line_number":246,"context_line":"            mask_password\u003dFalse,"},{"line_number":247,"context_line":"            is_admin\u003dFalse,"},{"line_number":248,"context_line":"            roles\u003dheaders[\u0027X-Roles\u0027].split(\u0027,\u0027))"},{"line_number":249,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"fa81d914_bde2e52c","line":246,"updated":"2015-01-30 14:52:05.000000000","message":"Shouldn\u0027t RequestContext be called with mask_password\u003dTrue if the user isn\u0027t an admin? Also, seems like this test should be in the TestContextHook class.","commit_id":"f18160b3535a3b1a40aa103ed2fdf62dbb1be03a"}],"ironic/tests/api/v1/test_nodes.py":[{"author":{"_account_id":10343,"name":"Jim Rollenhagen","email":"jim@jimrollenhagen.com","username":"jimrollenhagen"},"change_message_id":"b2927804ebb90aa7b833db6f8bb91809338d4cd9","unresolved":false,"context_lines":[{"line_number":119,"context_line":"        self.assertEqual(node.uuid, data[\u0027uuid\u0027])"},{"line_number":120,"context_line":"        self.assertIn(\u0027driver\u0027, data)"},{"line_number":121,"context_line":"        self.assertIn(\u0027driver_info\u0027, data)"},{"line_number":122,"context_line":"        self.assertEqual(\u0027******\u0027, data[\u0027driver_info\u0027][\u0027fake_password\u0027])"},{"line_number":123,"context_line":"        self.assertIn(\u0027extra\u0027, data)"},{"line_number":124,"context_line":"        self.assertIn(\u0027properties\u0027, data)"},{"line_number":125,"context_line":"        self.assertIn(\u0027chassis_uuid\u0027, data)"}],"source_content_type":"text/x-python","patch_set":4,"id":"fa81d914_bd5025d5","line":122,"updated":"2015-01-30 14:52:05.000000000","message":"Could we add an assertion to test not all driver_info is masked, e.g. self.assertEqual(\u0027bar\u0027, data[\u0027driver_info\u0027][\u0027foo\u0027])","commit_id":"f18160b3535a3b1a40aa103ed2fdf62dbb1be03a"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"82f2f82f46df8e17bada17d74fa86680e49b09d4","unresolved":false,"context_lines":[{"line_number":119,"context_line":"        self.assertEqual(node.uuid, data[\u0027uuid\u0027])"},{"line_number":120,"context_line":"        self.assertIn(\u0027driver\u0027, data)"},{"line_number":121,"context_line":"        self.assertIn(\u0027driver_info\u0027, data)"},{"line_number":122,"context_line":"        self.assertEqual(\u0027******\u0027, data[\u0027driver_info\u0027][\u0027fake_password\u0027])"},{"line_number":123,"context_line":"        self.assertIn(\u0027extra\u0027, data)"},{"line_number":124,"context_line":"        self.assertIn(\u0027properties\u0027, data)"},{"line_number":125,"context_line":"        self.assertIn(\u0027chassis_uuid\u0027, data)"}],"source_content_type":"text/x-python","patch_set":4,"id":"fa81d914_1d25b15b","line":122,"in_reply_to":"fa81d914_bd5025d5","updated":"2015-01-30 14:55:15.000000000","message":"+1","commit_id":"f18160b3535a3b1a40aa103ed2fdf62dbb1be03a"}],"ironic/tests/test_policy.py":[{"author":{"_account_id":4992,"name":"malini-k-bhandaru","email":"malini.k.bhandaru@intel.com","username":"malini-k-bhandaru"},"change_message_id":"7a6ff2d400d45a6ebe81f3a7e063415cd2b20271","unresolved":false,"context_lines":[{"line_number":45,"context_line":""},{"line_number":46,"context_line":"    def test_mask_password(self):"},{"line_number":47,"context_line":"        creds \u003d {\u0027roles\u0027: [u\u0027admin\u0027], \u0027tenant\u0027: \u0027demo\u0027}"},{"line_number":48,"context_line":"        self.assertTrue(policy.enforce(\u0027mask_password\u0027, creds, creds))"},{"line_number":49,"context_line":""},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"class PolicyTestCaseNegative(base.TestCase):"}],"source_content_type":"text/x-python","patch_set":5,"id":"da86d52c_17d8b71c","line":48,"updated":"2015-01-31 12:53:41.000000000","message":"Would have at first glance expected this to be an assertFalse for role\u003d\u003dadmin or tenant\u003d\u003dadmin, but in the context of fake-policy \"mask_password\": \"not tenant:admin\" makes sense.","commit_id":"42615c68d48e17fc3c7833a713135e68238a896b"}]}
