Add an API for managing OAuth applications

Review Request #9002 — Created June 8, 2017 and submitted

Information

Review Board
release-3.0.x

Reviewers

OAuth applications can now be created and managed via the oauth-apps/
API endpoint. Application information is only available to (1) the user
who created the app, (2) site administrators, and (3) Local Site
administrators when the application is associated with a Local Site.

Ran unit tests.

Description From Last Updated

W293 blank line contains whitespace

reviewbotreviewbot

W293 blank line contains whitespace

reviewbotreviewbot

W293 blank line contains whitespace

reviewbotreviewbot

W293 blank line contains whitespace

reviewbotreviewbot

W293 blank line contains whitespace

reviewbotreviewbot

W291 trailing whitespace

reviewbotreviewbot

W293 blank line contains whitespace

reviewbotreviewbot

W293 blank line contains whitespace

reviewbotreviewbot

W293 blank line contains whitespace

reviewbotreviewbot

W293 blank line contains whitespace

reviewbotreviewbot

W293 blank line contains whitespace

reviewbotreviewbot

W293 blank line contains whitespace

reviewbotreviewbot

W293 blank line contains whitespace

reviewbotreviewbot

W293 blank line contains whitespace

reviewbotreviewbot

W293 blank line contains whitespace

reviewbotreviewbot

W293 blank line contains whitespace

reviewbotreviewbot

W293 blank line contains whitespace

reviewbotreviewbot

W293 blank line contains whitespace

reviewbotreviewbot

E303 too many blank lines (2)

reviewbotreviewbot

W293 blank line contains whitespace

reviewbotreviewbot

W293 blank line contains whitespace

reviewbotreviewbot

W293 blank line contains whitespace

reviewbotreviewbot

W293 blank line contains whitespace

reviewbotreviewbot

W293 blank line contains whitespace

reviewbotreviewbot

W293 blank line contains whitespace

reviewbotreviewbot

W293 blank line contains whitespace

reviewbotreviewbot

W293 blank line contains whitespace

reviewbotreviewbot

W293 blank line contains whitespace

reviewbotreviewbot

E702 multiple statements on one line (semicolon)

reviewbotreviewbot

E305 expected 2 blank lines after class or function definition, found 1

reviewbotreviewbot

W293 blank line contains whitespace

reviewbotreviewbot

E303 too many blank lines (2)

reviewbotreviewbot

E303 too many blank lines (5)

reviewbotreviewbot

F811 redefinition of unused 'test_get_filtered' from line 77

reviewbotreviewbot

E303 too many blank lines (2)

reviewbotreviewbot

): should be on the previous line. Also, docstring?

daviddavid

Module docstring?

daviddavid

Swap these two lines.

daviddavid

Swap these two lines.

daviddavid

You can enforce the actual values by doing: 'type': (Application.GRANT_AUTHORIZATION_CODE, Application.GRANT_CLIENT_CREDENTIALS, Application.GRANT_IMPLICIT, Application.GRANT_PASSWORD)

daviddavid

This can also use 'type': (Application.CLIENT_CONFIDENTIAL, Application.CLIENT_PUBLIC)

daviddavid

Can this (and the other changes in this file) be rolled up into existing review requests?

chipx86chipx86

Needs a space before "stylesheet"

chipx86chipx86

, optional

chipx86chipx86

, optional

chipx86chipx86

, optional

chipx86chipx86

, optional

chipx86chipx86

Can you put GRANT_PASSWORD on its own line?

chipx86chipx86

I'd like to include more information on what this is, for those new to OAuth2.

chipx86chipx86

Can you break the string after the newlines, so it reads more like paragraphs?

chipx86chipx86

Missing a period. Should also include a bit more information on what this is. In general, the more explicit the …

chipx86chipx86

Can you break the strings at newlines?

chipx86chipx86

Can you break at the newlines?

chipx86chipx86

Local Site

chipx86chipx86

Local Site

chipx86chipx86

Rather than having all this here, let's add permission checks to Application. There should be an is_accessible_by for this and …

chipx86chipx86

Should use local_site.is_mutable_by(request.user).

chipx86chipx86

This can fit on one line.

chipx86chipx86

, optional

chipx86chipx86

, optional

chipx86chipx86

local_site.is_mutable_by(request.user)

chipx86chipx86

This is already provided by the base class.

chipx86chipx86

We need a @webapi_request_fields that documents username=.

chipx86chipx86

These are already provided by the base class.

chipx86chipx86

No blank line.

chipx86chipx86

I don't really love the complexity of building a temp function that does its own caching. The logic should probably …

chipx86chipx86

Can you put this in parens? (the superuser or ...).

chipx86chipx86

local_site.is_mutable_by(request.user).

chipx86chipx86

How about "You don't have permission to set this field."? We may very well want special permissions for modifying OAuth2 …

chipx86chipx86

values_list would go on the next line.

chipx86chipx86

We should default this to None up above, instead of setting it here and in the else: further down.

chipx86chipx86

Let's remove the "on this LocalSite." RBCommons users are just going to ask questions about it. From their point of …

chipx86chipx86

How about instead of this, we have a not_owner_status_code and not_owner_error, defaulting to 403 and PERMISSION_DENIED, respectively. Then it's a …

chipx86chipx86

resources should go before tests.

chipx86chipx86

Missing a docstring.

chipx86chipx86

This sort of thing is repeated an aweful lot. How about giving _make_applications a filter argument?

chipx86chipx86

Can we use keyword arguments for all these? It'll make it more self-documenting.

chipx86chipx86

Missing a docstring.

chipx86chipx86

No need for these blank lines. They're all setting common state for the tests.

chipx86chipx86

Can you put a blank line before/after the api_get? It's helpful to have a block of setup code, a block …

chipx86chipx86

W293 blank line contains whitespace

reviewbotreviewbot

W293 blank line contains whitespace

reviewbotreviewbot

F401 'djblets.webapi.errors.PERMISSION_DENIED' imported but unused

reviewbotreviewbot

E131 continuation line unaligned for hanging indent

reviewbotreviewbot

E131 continuation line unaligned for hanging indent

reviewbotreviewbot

F401 'djblets.webapi.errors.DOES_NOT_EXIST' imported but unused

reviewbotreviewbot

W293 blank line contains whitespace

reviewbotreviewbot

Blank line between these two.

daviddavid

i before s

daviddavid
Checks run (1 failed, 1 succeeded)
flake8 failed.
JSHint passed.

flake8

brennie
Review request changed
Change Summary:

whitespace

Checks run (1 failed, 1 succeeded)

flake8 failed.
JSHint passed.

flake8

brennie
david
  1. 
      
  2. reviewboard/testing/testcase.py (Diff revision 3)
     
     
     
    Show all issues

    ): should be on the previous line. Also, docstring?

  3. Show all issues

    Module docstring?

  4. reviewboard/webapi/resources/oauth_app.py (Diff revision 3)
     
     
     
    Show all issues

    Swap these two lines.

  5. reviewboard/webapi/resources/oauth_app.py (Diff revision 3)
     
     
     
    Show all issues

    Swap these two lines.

  6. reviewboard/webapi/resources/oauth_app.py (Diff revision 3)
     
     
     
     
     
     
     
     
    Show all issues

    You can enforce the actual values by doing:

    'type': (Application.GRANT_AUTHORIZATION_CODE,
             Application.GRANT_CLIENT_CREDENTIALS,
             Application.GRANT_IMPLICIT,
             Application.GRANT_PASSWORD)
    
  7. reviewboard/webapi/resources/oauth_app.py (Diff revision 3)
     
     
     
     
     
     
     
    Show all issues

    This can also use 'type': (Application.CLIENT_CONFIDENTIAL, Application.CLIENT_PUBLIC)

  8. 
      
brennie
brennie
brennie
brennie
chipx86
  1. 
      
  2. reviewboard/oauth/forms.py (Diff revision 7)
     
     
    Show all issues

    Can this (and the other changes in this file) be rolled up into existing review requests?

  3. Show all issues

    Needs a space before "stylesheet"

  4. reviewboard/testing/testcase.py (Diff revision 7)
     
     
    Show all issues

    , optional

  5. reviewboard/testing/testcase.py (Diff revision 7)
     
     
    Show all issues

    , optional

  6. reviewboard/testing/testcase.py (Diff revision 7)
     
     
    Show all issues

    , optional

  7. reviewboard/testing/testcase.py (Diff revision 7)
     
     
    Show all issues

    , optional

  8. Show all issues

    Can you put GRANT_PASSWORD on its own line?

  9. Show all issues

    I'd like to include more information on what this is, for those new to OAuth2.

  10. reviewboard/webapi/resources/oauth_app.py (Diff revision 7)
     
     
     
    Show all issues

    Can you break the string after the newlines, so it reads more like paragraphs?

  11. Show all issues

    Missing a period.

    Should also include a bit more information on what this is. In general, the more explicit the descriptions/help text, the more time we save others and ourselves.

  12. Show all issues

    Can you break the strings at newlines?

  13. Show all issues

    Can you break at the newlines?

  14. Show all issues

    Local Site

  15. Show all issues

    Local Site

  16. reviewboard/webapi/resources/oauth_app.py (Diff revision 7)
     
     
     
     
     
     
     
    Show all issues

    Rather than having all this here, let's add permission checks to Application. There should be an is_accessible_by for this and is_mutable_by for the modify/delete checks (which are free to check is_accessible_by).

  17. Show all issues

    Should use local_site.is_mutable_by(request.user).

  18. reviewboard/webapi/resources/oauth_app.py (Diff revision 7)
     
     
     
    Show all issues

    This can fit on one line.

  19. Show all issues

    , optional

  20. Show all issues

    , optional

  21. Show all issues

    local_site.is_mutable_by(request.user)

  22. Show all issues

    This is already provided by the base class.

  23. Show all issues

    We need a @webapi_request_fields that documents username=.

  24. Show all issues

    These are already provided by the base class.

  25. reviewboard/webapi/resources/oauth_app.py (Diff revision 7)
     
     
     
     
    Show all issues

    No blank line.

  26. Show all issues

    I don't really love the complexity of building a temp function that does its own caching. The logic should probably change instead.

    How about:

    skip_authorization = parsed_request_fields.get('skip_authorization', False)
    is_owner = (username is not None and
                username != request.user.username)
    
    if skip_authorization or is_owner:
        # The user wants to set a fields only available to administrators.
        # Check for permission first.
        if not (request.user.is_authenticated() and
                (request.user.is_superuser or
                 (...))):
            # The user doesn't have permission to modify these fields, so
            # return error messages for each of the fields they attempted to
            # modify.
            if skip_authorization:
                errors['skip_authorization'].append(...)
    
            if is_owner:
                errors['user'].append(...)
        else:
            # Start handling those fields.
            if is_owner:
                ...
    

    This gets rid of the need to build a temp function that caches on itself, and it separates out the permission checking from the rest of the logic.

    The User lookups would go in the else:. If the user doesn't have permission to set these fields, we shouldn't be giving them any information on whether the user they've set is valid. They should just get denied up-front.

  27. reviewboard/webapi/resources/oauth_app.py (Diff revision 7)
     
     
     
     
     
     
    Show all issues

    Can you put this in parens? (the superuser or ...).

  28. reviewboard/webapi/resources/oauth_app.py (Diff revision 7)
     
     
     
     
    Show all issues

    local_site.is_mutable_by(request.user).

  29. Show all issues

    How about "You don't have permission to set this field."? We may very well want special permissions for modifying OAuth2 entries for organizations without granting full admin privileges down the road.

  30. Show all issues

    values_list would go on the next line.

  31. Show all issues

    We should default this to None up above, instead of setting it here and in the else: further down.

  32. Show all issues

    Let's remove the "on this LocalSite." RBCommons users are just going to ask questions about it. From their point of view, their team's users are the entire set of users.

  33. reviewboard/webapi/tests/mixins.py (Diff revision 7)
     
     
    Show all issues

    How about instead of this, we have a not_owner_status_code and not_owner_error, defaulting to 403 and PERMISSION_DENIED, respectively. Then it's a little more immediately clear what the purpose is, and it's not hard-coded for one specific use case.

    These should also have doc comments.

  34. reviewboard/webapi/tests/test_oauth_app.py (Diff revision 7)
     
     
     
     
    Show all issues

    resources should go before tests.

  35. Show all issues

    Missing a docstring.

  36. reviewboard/webapi/tests/test_oauth_app.py (Diff revision 7)
     
     
     
     
     
    Show all issues

    This sort of thing is repeated an aweful lot. How about giving _make_applications a filter argument?

  37. reviewboard/webapi/tests/test_oauth_app.py (Diff revision 7)
     
     
     
    Show all issues

    Can we use keyword arguments for all these? It'll make it more self-documenting.

  38. Show all issues

    Missing a docstring.

  39. reviewboard/webapi/tests/test_oauth_app.py (Diff revision 7)
     
     
     
     
     
     
     
     
    Show all issues

    No need for these blank lines. They're all setting common state for the tests.

  40. reviewboard/webapi/tests/test_oauth_app.py (Diff revision 7)
     
     
     
     
     
    Show all issues

    Can you put a blank line before/after the api_get?

    It's helpful to have a block of setup code, a block of test execution, and a block of assertions.

    Here and below.

  41. 
      
brennie
Review request changed
Change Summary:

Addressed Christian's issues.

Checks run (1 failed, 1 succeeded)

flake8 failed.
JSHint passed.

flake8

brennie
brennie
brennie
david
  1. 
      
  2. reviewboard/webapi/resources/oauth_app.py (Diff revision 9)
     
     
     
    Show all issues

    Blank line between these two.

  3. reviewboard/webapi/resources/oauth_app.py (Diff revision 9)
     
     
     
    Show all issues

    i before s

  4. 
      
brennie
david
  1. Ship It!
  2. 
      
brennie
Review request changed
Status:
Completed
Change Summary:
Pushed to release-3.0.x (2993ce0)