Fixed permission failure with status message update

Review Request #7922 — Created Jan. 30, 2016 and discarded

Information

Review Board
release-2.0.x

Reviewers

When users with the "can_change_status" permission try to edit the close message, a permission error occurs. This is because when checking for permission, users with no modify permission are all excluded.
Code is changed to include the case of "can_change_status" permission.
Added test case to cover case where user with "can_change_status" permission but no modify permission should get permission error when trying to edit changenum; the case where user with "can_change_status" permission but no modify permission should get permission error when trying to add extra data; the case where user with "can_edit_reviewrequest" permission but no status mutation permission should get permission error when trying to modify status.

Manual testing and Review Board Unit Testing

Description From Last Updated

Col: 14 E127 continuation line over-indented for visual indent

reviewbotreviewbot

Col: 35 W291 trailing whitespace

reviewbotreviewbot

Col: 74 W291 trailing whitespace

reviewbotreviewbot

Col: 9 E128 continuation line under-indented for visual indent

reviewbotreviewbot

This worries me. The logic here says: "If you're modifying changenum or extra_fields and you don't have modify permissions, AND …

mike_conleymike_conley

local variable 'rsp' is assigned to but never used

reviewbotreviewbot

Col: 25 E231 missing whitespace after ':'

reviewbotreviewbot

This doesn't need parens around the first two conditions. (A and B) and C is equivalent to A and B …

brenniebrennie

So this change actually has a bigger impact than it first appears. Old logic was: "Return an error if we're …

chipx86chipx86

The """ should go on the next line.

brenniebrennie

You only embed this right into the payload, so it may aswell go there instead of being pulled out as …

brenniebrennie

Can you format this as: self.api_put(get_review_request_item_url(r.display_id), { 'changenum': changenum, }, expected_status=403)

brenniebrennie
reviewbot
  1. Tool: Pyflakes
    Processed Files:
        reviewboard/webapi/resources/review_request.py
    
    
    
    Tool: PEP8 Style Checker
    Processed Files:
        reviewboard/webapi/resources/review_request.py
    
    
  2. 
      
SH
mike_conley
  1. Just adding a note here so that we don't forget - can you please run the automated nose tests and update the Testing Done section with their result?

  2. 
      
SH
reviewbot
  1. Tool: Pyflakes
    Processed Files:
        reviewboard/webapi/resources/review_request.py
    
    
    
    Tool: PEP8 Style Checker
    Processed Files:
        reviewboard/webapi/resources/review_request.py
    
    
  2. Show all issues
    Col: 14
     E127 continuation line over-indented for visual indent
    
  3. 
      
SH
reviewbot
  1. Tool: Pyflakes
    Processed Files:
        reviewboard/webapi/resources/review_request.py
    
    
    
    Tool: PEP8 Style Checker
    Processed Files:
        reviewboard/webapi/resources/review_request.py
    
    
  2. Show all issues
    Col: 35
     W291 trailing whitespace
    
  3. Show all issues
    Col: 74
     W291 trailing whitespace
    
  4. Show all issues
    Col: 9
     E128 continuation line under-indented for visual indent
    
  5. 
      
SH
reviewbot
  1. Tool: Pyflakes
    Processed Files:
        reviewboard/webapi/resources/review_request.py
    
    
    
    Tool: PEP8 Style Checker
    Processed Files:
        reviewboard/webapi/resources/review_request.py
    
    
  2. 
      
brennie
  1. Can you edit your description and remove the first line? It is already in the summary.

    Your description should mention the problem (i.e., the logic error) and how it was fixed.

    See this guide.

  2. 
      
SH
mike_conley
  1. Sorry this took so long, but I wanted to take a good long look at this! Great work on this - but I have a small concern. See below!

  2. Show all issues

    This worries me.

    The logic here says:

    "If you're modifying changenum or extra_fields and you don't have modify permissions, AND on top of that, if you don't have status mutable permissions, show a no access error".

    What I believe that leaves, however, is the case where a user doesn't have status mutation permissions, but didn't modify changenum or extra_fields.

    In that case, I believe we'll slip through this block, and attempt to write to the status of the review request. I think that's a security / permission problem.

    I think we should write some tests for this to be sure, because I'm mostly just assuming this via inspection and reading the PUT docs on the ReviewRequest WebAPI resource.

    Here's where tests should be written: https://github.com/reviewboard/reviewboard/blob/master/reviewboard/webapi/tests/test_review_request.py

  3. 
      
SH
reviewbot
  1. Tool: Pyflakes
    Processed Files:
        reviewboard/webapi/resources/review_request.py
        reviewboard/webapi/tests/test_review_request.py
    
    
    
    Tool: PEP8 Style Checker
    Processed Files:
        reviewboard/webapi/resources/review_request.py
        reviewboard/webapi/tests/test_review_request.py
    
    
  2. Show all issues
     local variable 'rsp' is assigned to but never used
    
  3. Show all issues
    Col: 25
     E231 missing whitespace after ':'
    
  4. 
      
SH
reviewbot
  1. Tool: Pyflakes
    Processed Files:
        reviewboard/webapi/resources/review_request.py
        reviewboard/webapi/tests/test_review_request.py
    
    
    
    Tool: PEP8 Style Checker
    Processed Files:
        reviewboard/webapi/resources/review_request.py
        reviewboard/webapi/tests/test_review_request.py
    
    
  2. 
      
brennie
  1. 
      
  2. reviewboard/webapi/resources/review_request.py (Diff revision 6)
     
     
     
     
    Show all issues

    This doesn't need parens around the first two conditions.
    (A and B) and C is equivalent to A and B and C.

  3. Show all issues

    The """ should go on the next line.

  4. Show all issues

    You only embed this right into the payload, so it may aswell go there instead of being pulled out as a var.

  5. reviewboard/webapi/tests/test_review_request.py (Diff revision 6)
     
     
     
     
     
    Show all issues

    Can you format this as:

    self.api_put(get_review_request_item_url(r.display_id),
                 {
                     'changenum': changenum,
                 },
                 expected_status=403)
    
  6. 
      
chipx86
  1. 
      
  2. reviewboard/webapi/resources/review_request.py (Diff revision 6)
     
     
     
     
    Show all issues

    So this change actually has a bigger impact than it first appears.

    Old logic was: "Return an error if we're mutating a field without permission, or we're changing status without permission."

    New logic is: "Return an error only if we are disallowed both from modifying and from updating a status."

    This means that if you have permission to change status but not to modify, you can get past this point. Even if you're not changing status. This means that, further down, you're allowed to set extra_data, and at the very least, you're allowed to trigger a save (which will update the timestamp and trigger signals, triggering webhooks, possibly triggering extension behavior).

    Let's give another hypothetical where you're allowed to edit but not change status (say we let an extension block that off, so it must be automated). We'd now let you through here, and into the block below where status is being changed. The old code would have caught this (status change requested and no permission == error).

    So that or was pretty important. What we probably need to do, to fix that bug and these situations, is to:

    1. Calculate these permission checks once, and store in a variable (so we don't have any expensive calculations happening more than once).
    2. Wrap the entire status checking block with the status permission check.
    3. Wrap the whole changenum block (actually from changed_fields through the save) in the other status check.
    4. Just to completely sanity-check, before saving, assert that we were allowed to get there based on one of those permission checks being True.
    1. I just realized with the code further down, we do bail before saving, but only if a changenum is specified.

    2. Oh, and we shoud probably have unit tests for each one of those possible conditions, just to be super safe. Check that we don't so much as save the review request unless we're really allowed to.

  3. 
      
SH
reviewbot
  1. Tool: Pyflakes
    Processed Files:
        reviewboard/webapi/resources/review_request.py
        reviewboard/webapi/tests/test_review_request.py
    
    
    
    Tool: PEP8 Style Checker
    Processed Files:
        reviewboard/webapi/resources/review_request.py
        reviewboard/webapi/tests/test_review_request.py
    
    
  2. 
      
SH
reviewbot
  1. Tool: Pyflakes
    Processed Files:
        reviewboard/webapi/resources/review_request.py
        reviewboard/webapi/tests/test_review_request.py
    
    
    
    Tool: PEP8 Style Checker
    Processed Files:
        reviewboard/webapi/resources/review_request.py
        reviewboard/webapi/tests/test_review_request.py
    
    
  2. 
      
david
Review request changed
Status:
Discarded