Add support for using API tokens for authentication.

Review Request #6079 — Created July 8, 2014 and submitted

Information

Review Board
master
df7d622...

Reviewers

This introduces new auth and webapi auth backends for performing API
requests using an API token. Users can have zero or more API tokens
linked to their account, and any will be valid for authentication. The
goal is to allow tokens for different access levels (read/write,
read-only) and, down the road, scopes.

Clients can use these when talking to the API by passing
Authorization: token <token_value> in the request. This will
authenticate the owner of that token for the API requests.

Tokens cannot be used to authenticate through the website.

For now, tokens must be created through the admin UI. Further changes
are coming to make the usage of tokens more practical.

I tested with 2 LocalSites and the global site.

I created three auth tokens: One unbound to a LocalSite, and one bound to each LocalSite.

Using curl, I attempted to access /api/session/ on the global site and on each LocalSite using each token. Results:

  1. Global token could reach the global /api/session/ and that of each LocalSite.
  2. LocalSite token 1 could only reach /s/site1/api/session/, and got a Permission Denied elsewhere.
  3. Same behavior for LocalSite token 2, except it could only reach /s/site2/api/session/.

Specifying an invalid token gave me an authentication error.

Unit tests pass (except that some on master haven't been updated for the function renames, but those are irrelevant to these changes).

Description From Last Updated

'from settings_local import *' used; unable to detect undefined names

reviewbotreviewbot

'PIPELINE_CSS' imported but unused

reviewbotreviewbot

'PIPELINE_JS' imported but unused

reviewbotreviewbot

'from settings_local import *' used; unable to detect undefined names

reviewbotreviewbot

'PIPELINE_CSS' imported but unused

reviewbotreviewbot

'PIPELINE_JS' imported but unused

reviewbotreviewbot

The second line here isn't indented properly (it should be inside the hashlib.sha1() call). You can also get rid of …

daviddavid

This isn't inside an exception handler so exc_info doesn't mean anything.

daviddavid

Is this meant to be returned via the API, or shown in the UI? If the former, we don't usually …

daviddavid

This could then just be TokenAuthBackend, to make it clear that it's not specifically an API backend.

daviddavid

So I just noticed the inconsistency in the names here. How about naming the second one WebAPITokenAuthBackend?

daviddavid

'from settings_local import *' used; unable to detect undefined names

reviewbotreviewbot

'PIPELINE_CSS' imported but unused

reviewbotreviewbot

'PIPELINE_JS' imported but unused

reviewbotreviewbot

'django_reset' imported but unused

reviewbotreviewbot

'from settings_local import *' used; unable to detect undefined names

reviewbotreviewbot

'PIPELINE_JS' imported but unused

reviewbotreviewbot

'PIPELINE_CSS' imported but unused

reviewbotreviewbot

undefined name 'APITokenWebAPIAuthBackend'

reviewbotreviewbot

'django_reset' imported but unused

reviewbotreviewbot

'from settings_local import *' used; unable to detect undefined names

reviewbotreviewbot

'PIPELINE_JS' imported but unused

reviewbotreviewbot

'PIPELINE_CSS' imported but unused

reviewbotreviewbot
chipx86
reviewbot
  1. Tool: PEP8 Style Checker
    Processed Files:
        reviewboard/admin/siteconfig.py
        reviewboard/webapi/base.py
        reviewboard/settings.py
        reviewboard/webapi/models.py
        reviewboard/webapi/errors.py
        reviewboard/webapi/auth_backends.py
        reviewboard/webapi/admin.py
        reviewboard/webapi/decorators.py
        reviewboard/webapi/managers.py
    
    
    
    Tool: Pyflakes
    Processed Files:
        reviewboard/admin/siteconfig.py
        reviewboard/webapi/base.py
        reviewboard/settings.py
        reviewboard/webapi/models.py
        reviewboard/webapi/errors.py
        reviewboard/webapi/auth_backends.py
        reviewboard/webapi/admin.py
        reviewboard/webapi/decorators.py
        reviewboard/webapi/managers.py
    
    
  2. reviewboard/settings.py (Diff revision 2)
     
     
    Show all issues
     'from settings_local import *' used; unable to detect undefined names
    
  3. reviewboard/settings.py (Diff revision 2)
     
     
    Show all issues
     'PIPELINE_CSS' imported but unused
    
  4. reviewboard/settings.py (Diff revision 2)
     
     
    Show all issues
     'PIPELINE_JS' imported but unused
    
  5. 
      
reviewbot
  1. Tool: Pyflakes
    Processed Files:
        reviewboard/admin/siteconfig.py
        reviewboard/webapi/models.py
        reviewboard/settings.py
        reviewboard/webapi/errors.py
        reviewboard/webapi/auth_backends.py
        reviewboard/webapi/admin.py
        reviewboard/webapi/decorators.py
        reviewboard/webapi/managers.py
    
    
    
    Tool: PEP8 Style Checker
    Processed Files:
        reviewboard/admin/siteconfig.py
        reviewboard/webapi/models.py
        reviewboard/settings.py
        reviewboard/webapi/errors.py
        reviewboard/webapi/auth_backends.py
        reviewboard/webapi/admin.py
        reviewboard/webapi/decorators.py
        reviewboard/webapi/managers.py
    
    
  2. reviewboard/settings.py (Diff revision 1)
     
     
    Show all issues
     'from settings_local import *' used; unable to detect undefined names
    
  3. reviewboard/settings.py (Diff revision 1)
     
     
    Show all issues
     'PIPELINE_CSS' imported but unused
    
  4. reviewboard/settings.py (Diff revision 1)
     
     
    Show all issues
     'PIPELINE_JS' imported but unused
    
  5. 
      
david
  1. 
      
  2. reviewboard/webapi/managers.py (Diff revision 2)
     
     
     
    Show all issues

    The second line here isn't indented properly (it should be inside the hashlib.sha1() call). You can also get rid of the outer parens.

  3. reviewboard/webapi/managers.py (Diff revision 2)
     
     
    Show all issues

    This isn't inside an exception handler so exc_info doesn't mean anything.

  4. reviewboard/webapi/managers.py (Diff revision 2)
     
     
    Show all issues

    Is this meant to be returned via the API, or shown in the UI? If the former, we don't usually translate API strings, right?

    1. It's used for both. We don't usually translate, but the strings are for display purposes and not for parsing. I'm pretty sure we have other errors that can be returned by the API that are localized.

    2. Yep, definitely errors used elsewhere. DiffTooBigError's string is localized and returned. Same with EmptyDiffError, ShortSHA1Error. Probably others.

      We may just want to localize for all errors, really.

  5. 
      
chipx86
reviewbot
  1. Tool: PEP8 Style Checker
    Processed Files:
        reviewboard/admin/siteconfig.py
        reviewboard/webapi/base.py
        reviewboard/settings.py
        reviewboard/webapi/models.py
        reviewboard/webapi/errors.py
        reviewboard/webapi/auth_backends.py
        reviewboard/webapi/admin.py
        reviewboard/webapi/decorators.py
        reviewboard/webapi/managers.py
    
    
    
    Tool: Pyflakes
    Processed Files:
        reviewboard/admin/siteconfig.py
        reviewboard/webapi/base.py
        reviewboard/settings.py
        reviewboard/webapi/models.py
        reviewboard/webapi/errors.py
        reviewboard/webapi/auth_backends.py
        reviewboard/webapi/admin.py
        reviewboard/webapi/decorators.py
        reviewboard/webapi/managers.py
    
    
  2. reviewboard/settings.py (Diff revision 3)
     
     
    Show all issues
     'from settings_local import *' used; unable to detect undefined names
    
  3. reviewboard/settings.py (Diff revision 3)
     
     
    Show all issues
     'PIPELINE_CSS' imported but unused
    
  4. reviewboard/settings.py (Diff revision 3)
     
     
    Show all issues
     'PIPELINE_JS' imported but unused
    
  5. 
      
david
  1. 
      
  2. reviewboard/admin/siteconfig.py (Diff revision 3)
     
     
    Show all issues

    This could then just be TokenAuthBackend, to make it clear that it's not specifically an API backend.

  3. reviewboard/settings.py (Diff revision 3)
     
     
     
    Show all issues

    So I just noticed the inconsistency in the names here. How about naming the second one WebAPITokenAuthBackend?

    1. The reason for that naming is because we have a WebAPIAuthBackend in here, and a standard AuthBackend in that module.

    2. Yeah, I'm saying that I'd prefer it as 'TokenAuthBackend' and 'WebAPITokenAuthBackend'

  4. 
      
chipx86
reviewbot
  1. Tool: PEP8 Style Checker
    Processed Files:
        reviewboard/admin/siteconfig.py
        reviewboard/webapi/base.py
        reviewboard/settings.py
        reviewboard/webapi/models.py
        reviewboard/webapi/errors.py
        reviewboard/webapi/auth_backends.py
        reviewboard/webapi/admin.py
        reviewboard/webapi/decorators.py
        reviewboard/webapi/managers.py
    
    
    
    Tool: Pyflakes
    Processed Files:
        reviewboard/admin/siteconfig.py
        reviewboard/webapi/base.py
        reviewboard/settings.py
        reviewboard/webapi/models.py
        reviewboard/webapi/errors.py
        reviewboard/webapi/auth_backends.py
        reviewboard/webapi/admin.py
        reviewboard/webapi/decorators.py
        reviewboard/webapi/managers.py
    
    
  2. reviewboard/settings.py (Diff revision 4)
     
     
    Show all issues
     'django_reset' imported but unused
    
  3. reviewboard/settings.py (Diff revision 4)
     
     
    Show all issues
     'from settings_local import *' used; unable to detect undefined names
    
  4. reviewboard/settings.py (Diff revision 4)
     
     
    Show all issues
     'PIPELINE_JS' imported but unused
    
  5. reviewboard/settings.py (Diff revision 4)
     
     
    Show all issues
     'PIPELINE_CSS' imported but unused
    
  6. reviewboard/webapi/auth_backends.py (Diff revision 4)
     
     
    Show all issues
     undefined name 'APITokenWebAPIAuthBackend'
    
  7. 
      
chipx86
reviewbot
  1. Tool: Pyflakes
    Processed Files:
        reviewboard/admin/siteconfig.py
        reviewboard/webapi/base.py
        reviewboard/settings.py
        reviewboard/webapi/models.py
        reviewboard/webapi/errors.py
        reviewboard/webapi/auth_backends.py
        reviewboard/webapi/admin.py
        reviewboard/webapi/decorators.py
        reviewboard/webapi/managers.py
    
    
    
    Tool: PEP8 Style Checker
    Processed Files:
        reviewboard/admin/siteconfig.py
        reviewboard/webapi/base.py
        reviewboard/settings.py
        reviewboard/webapi/models.py
        reviewboard/webapi/errors.py
        reviewboard/webapi/auth_backends.py
        reviewboard/webapi/admin.py
        reviewboard/webapi/decorators.py
        reviewboard/webapi/managers.py
    
    
  2. reviewboard/settings.py (Diff revision 5)
     
     
    Show all issues
     'django_reset' imported but unused
    
  3. reviewboard/settings.py (Diff revision 5)
     
     
    Show all issues
     'from settings_local import *' used; unable to detect undefined names
    
  4. reviewboard/settings.py (Diff revision 5)
     
     
    Show all issues
     'PIPELINE_JS' imported but unused
    
  5. reviewboard/settings.py (Diff revision 5)
     
     
    Show all issues
     'PIPELINE_CSS' imported but unused
    
  6. 
      
david
  1. Ship It!

  2. 
      
chipx86
Review request changed
Status:
Completed
Change Summary:
Pushed to master (8ef5f85)