• 
      

    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

    reviewbot reviewbot

    W293 blank line contains whitespace

    reviewbot reviewbot

    W293 blank line contains whitespace

    reviewbot reviewbot

    W293 blank line contains whitespace

    reviewbot reviewbot

    W293 blank line contains whitespace

    reviewbot reviewbot

    W291 trailing whitespace

    reviewbot reviewbot

    W293 blank line contains whitespace

    reviewbot reviewbot

    W293 blank line contains whitespace

    reviewbot reviewbot

    W293 blank line contains whitespace

    reviewbot reviewbot

    W293 blank line contains whitespace

    reviewbot reviewbot

    W293 blank line contains whitespace

    reviewbot reviewbot

    W293 blank line contains whitespace

    reviewbot reviewbot

    W293 blank line contains whitespace

    reviewbot reviewbot

    W293 blank line contains whitespace

    reviewbot reviewbot

    W293 blank line contains whitespace

    reviewbot reviewbot

    W293 blank line contains whitespace

    reviewbot reviewbot

    W293 blank line contains whitespace

    reviewbot reviewbot

    W293 blank line contains whitespace

    reviewbot reviewbot

    E303 too many blank lines (2)

    reviewbot reviewbot

    W293 blank line contains whitespace

    reviewbot reviewbot

    W293 blank line contains whitespace

    reviewbot reviewbot

    W293 blank line contains whitespace

    reviewbot reviewbot

    W293 blank line contains whitespace

    reviewbot reviewbot

    W293 blank line contains whitespace

    reviewbot reviewbot

    W293 blank line contains whitespace

    reviewbot reviewbot

    W293 blank line contains whitespace

    reviewbot reviewbot

    W293 blank line contains whitespace

    reviewbot reviewbot

    W293 blank line contains whitespace

    reviewbot reviewbot

    E702 multiple statements on one line (semicolon)

    reviewbot reviewbot

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

    reviewbot reviewbot

    W293 blank line contains whitespace

    reviewbot reviewbot

    E303 too many blank lines (2)

    reviewbot reviewbot

    E303 too many blank lines (5)

    reviewbot reviewbot

    F811 redefinition of unused 'test_get_filtered' from line 77

    reviewbot reviewbot

    E303 too many blank lines (2)

    reviewbot reviewbot

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

    david david

    Module docstring?

    david david

    Swap these two lines.

    david david

    Swap these two lines.

    david david

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

    david david

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

    david david

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

    chipx86 chipx86

    Needs a space before "stylesheet"

    chipx86 chipx86

    , optional

    chipx86 chipx86

    , optional

    chipx86 chipx86

    , optional

    chipx86 chipx86

    , optional

    chipx86 chipx86

    Can you put GRANT_PASSWORD on its own line?

    chipx86 chipx86

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

    chipx86 chipx86

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

    chipx86 chipx86

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

    chipx86 chipx86

    Can you break the strings at newlines?

    chipx86 chipx86

    Can you break at the newlines?

    chipx86 chipx86

    Local Site

    chipx86 chipx86

    Local Site

    chipx86 chipx86

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

    chipx86 chipx86

    Should use local_site.is_mutable_by(request.user).

    chipx86 chipx86

    This can fit on one line.

    chipx86 chipx86

    , optional

    chipx86 chipx86

    , optional

    chipx86 chipx86

    local_site.is_mutable_by(request.user)

    chipx86 chipx86

    This is already provided by the base class.

    chipx86 chipx86

    We need a @webapi_request_fields that documents username=.

    chipx86 chipx86

    These are already provided by the base class.

    chipx86 chipx86

    No blank line.

    chipx86 chipx86

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

    chipx86 chipx86

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

    chipx86 chipx86

    local_site.is_mutable_by(request.user).

    chipx86 chipx86

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

    chipx86 chipx86

    values_list would go on the next line.

    chipx86 chipx86

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

    chipx86 chipx86

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

    chipx86 chipx86

    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 …

    chipx86 chipx86

    resources should go before tests.

    chipx86 chipx86

    Missing a docstring.

    chipx86 chipx86

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

    chipx86 chipx86

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

    chipx86 chipx86

    Missing a docstring.

    chipx86 chipx86

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

    chipx86 chipx86

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

    chipx86 chipx86

    W293 blank line contains whitespace

    reviewbot reviewbot

    W293 blank line contains whitespace

    reviewbot reviewbot

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

    reviewbot reviewbot

    E131 continuation line unaligned for hanging indent

    reviewbot reviewbot

    E131 continuation line unaligned for hanging indent

    reviewbot reviewbot

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

    reviewbot reviewbot

    W293 blank line contains whitespace

    reviewbot reviewbot

    Blank line between these two.

    david david

    i before s

    david david
    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)