codalab/codalab-cli — pull request #12 by cpoulain (2014-04-12 04:51:53+00:00)
Title: OAuth authentication

On the client side:

- As discussed, there is a single address to define the remote service. It is the address of the bundle service, for example, http://localhost:2800 or https://codalab.org/bundleservice. After prompting a user for name and password, `codalab_manager.authenticate` will now call a login method on the remote server.
- The login in `codalab_manager.authenticate` has been reworked to use a valid token when it is available and to refresh a token when it is nearing its expiration. Prompting for username and password is the last resort.
- `RemoteBundleClient` is the place where the OAuth token is automatically injected into the HTTP request.

On the server side:

- server.file_server.FileServer exposes the login method which is used to generate an OAuth token from a username and password (grant_type = "credentials) and to generate an OAuth token from a previously generated token (grant_type = "refresh_token"). The same FileServer class uses a customized XML RPC request handler to intercept the authorization information.
- The FileServer class delegates the logic of authenticating a user to an AuthHandler. There are two types of AuthHandler objects: 1) MockAuthHandler is useful for dev/test or to run a local server (cl server) without an OAuth authorization server; 2) OAuthHandler provides actual authentication using an OAuth authorization server.
- An AuthHandler instance is created by the CodaLab manager (method `auth_handler`) in the same way that the server's model is also created. The server configuration (in config.json) is expanded as follows:
```
# Mock setup
"server": {
"class": "SQLiteModel",
"host": "localhost",
"port": 2800,
"auth": {
"class": "MockAuthHandler",
}
},
# OAuth setup
"server": {
"class": "SQLiteModel",
"host": "localhost",
"port": 2800,
"auth": {
"class": "OAuthHandler",
"address": "http://localhost:8000",
"app_id": "5mtm-LWSTo...",
"app_key": "_bn2.WlOO..."
}
},
```

The *auth* block includes the *class* element to define the type of auth handler, either MockAuthHandler or OAuthHandler. For the latter, three additional parameters are required:
- *address*: the base URL of the OAuth authorization server. Examples are `http://localhost:8000` or `https://www.codalab.org`.
- app ID and key: client ID and secret used by the server to authenticate itself with the OAuth server. The method to generate an (ID, secret) pair is shown at the end of the description of https://github.com/codalab/codalab/pull/367.

The AuthHandler has two important methods: 1) generate_token which takes the user's credentials and turn them into an OAuth access token; and 2) validate_token which takes an access token and resolves it back into a user object. The user object obtained from a valid token is stored in the handler and made available via the current_user method. Additional logic (to be added on a per command basis) will be able to use this user information to further restrict access. A key assumption is that execution is single threaded, with one request at a time (which it is w/ the current setup of SimpleXMLPRCServer).

Note: before testing these changes it's probably a good idea to delete prior state.json files.