Skip to end of metadata
Go to start of metadata
Icon

Access to the User creation API is granted on a case-by-case basis and only where other methods of accessing and modifying user information will not work; namely on new platforms or devices which do not support a more standards-compliant way of accomplishing the same goals.

Introduction

The PBS UUA API is a system to remotely perform a subset of CRUD on two of the fundamental models of UUA database:

  • CustomUser
  • Website

It provides security using 2 legged OAuth.

Security

API connection is authenticated using 2 legged OAuth.

2-legged OAuth

Official Specifications for 2-legged OAuth

The two "legs" in 2-legged OAuth represent a Data Provider (UUA) and a relying party (Station Site). Using the 2-legged protocol, these two servers are able to securely exchange information through OAuth signed requests. However, there is no authorization step involved in 2-legged OAuth, which means that the application server must already have permission to access the data it is requesting from UUA. In the case of user-specific data, this is usually done in a separate channel. For example, when a user registers/ logs into UUA, they are asked to share their data with the Station site, which would allow the station site to access that user's data via 2-legged OAuth.

In regular OAuth, the relying party already has a consumer token but obtains and store separate access tokens for each user. In 2-legged OAuth, only one access token is necessary and is pre-approved.

The workflow can be described in the following manner:

A station site wants to update profile on behalf of a given user. The request is denied because the station site does not have permission to perform this action.

The station site requests UUA for pre-approved credentials. UUA confirms that UUA users can share their data with the station site.

Now when the station site attempts to access UUA user's profile data, UUA sees that the station site has been granted the permission to access this data, so the request is granted.

Authentication Mechanism

Each relying party requires the following 4 credentials to exist in approved state in UUA database to make an API call

  • API Consumer Token
    • Consumer Key
    • Consumer Secret
  • API Access Token
    • Access Key
    • Access Secret

Each API request will have to provide a combination of these tokens, timestamp and signature hash in the HTTP authentication header, which can be performed using standard OAuth clients.

Note that the 2-legged OAuth standard doesn't require the access tokens to be exchanged between servers. But in context of Django, which is user centric, we pass OAuth access tokens to establish the connection between UUA and different relying parties who use the API service.

Implementation

The OAuth tokens identify a Piston consumer instance that is linked to a Website except for consumers that are intended to have administrative privileges.

All relying parties will have a Website record on UUA. When the record is created, the following will occur:

  • A piston consumer object is created
    • The user foreign key in the consumer object is set to the user of the API administrator who created the website
    • "status" attribute of the token is set to "accepted" based on API access validation logic
    • Key & secret are generated randomly
  • A piston token of type 'access' is created
    • The user foreign key in the token object is set to the owner of the website
    • "is_approved" attribute of the token is set based on API access validation logic
    • Key & secret are generated randomly
  • UUA consumer shared key & secret key are generated automatically

How Consumers & Tokens are affected:

  • When a website is deactivated or its owner loses API administrator privilege, its consumer receives a "canceled" status and access token is deactivated by setting "is_approved" to false. At this point, the website can't be accessed over API anymore, neither can it create, read or update users
  • Consumer and access tokens can also be explicitly deactivated via django admin panel

Request Validity Period:

  • Each issued request is valid for 300 seconds.

Authorization

On top of OAuth based security, relying parties have limited data set to operate on, restricted by their identity. Restriction on individual API calls are detailed at the end of method descriptions.

The general mechanism of authorization is discussed in this section.

When an API request is received, the intended action can classified into the following categories:

  • Actions that any relying party can perform e.g. verify user credential, create user, update user
  • Actions that only API administrators can perform e.g. create website, retrieve website information, update website

Actions that any relying party can perform

No relying party is capable of retrieving, creating or updating websites

Actions that API administrators can perform

Workflow for actions such as creating websites is determined is by looking up the privilege of the user connected to the consumer. If the user of the consumer is a API administrator, then the consumer is considered to have administration privileges.

Only a consumer belonging to a API administrator can retrieve information on and update the website it owns. When processing requests initiating such actions, the consumer's user is matched against owner attribute of the website instance. If they don't match, the processing stops and the relying party receives a strict subset of the following response:

If a consumer without administration privileges attempts to make an API call that requires such, it will receive a: HTTP 401 PBS UUA API authentication error

Relying Party Security

We assume the relying party will be implementing the following:

  • HTTPS for login, registration and profile update pages
  • Captcha for failed login and registration pages

Operations on Data Models

Operations on CustomUser

Following remote operations are available to perform on CustomUser objects

  • Credential Verification
  • User Creation
  • User Update

Credential Verification

Input

Credential verification call takes an email address and password as input:

Output

If the credential was valid the RP receives the following:

If not valid, RP receives the following:

Error messages that apply to all of the above fields and not mentioned above are:

  • This field is required

Restrictions

Given a correct pair of email and password, any relying party is able to issue a login nonce for any PBS UUA user

Relying Party Responsibilities

The RP should do the following before calling UUA API for validation:

  • Check for minimum and maximum length of input. Values are provided below:

  • Captcha (Activate captcha upon a failed login attempt)

These checks should be performed both in the frontend using JS and in the backend using server side scripting

User Creation

Using this API method, a relying party will be able to create users remotely.

Input

Output

If the input passes validation checks on all fields which are exactly the same as the validations performed when a user registers on the UUA site except for Captcha. Captcha will be implemented by relying party.

If successful, the relying party receives the following data:

Depending on what fields were invalid, the error response will be a strict subset of the following:

Error messages that apply to all of the above fields and not mentioned above are:

  • This field is required

Restrictions

Any relying party with valid OAuth credential is able to create a new user

Relying Party Responsibilities

The RP should do the following before calling UUA API for validation:

  • Check for minimum and maximum length of input. Values are provided below:

  • Check for unacceptable characters in input. Regular expression is provided below:

  • Captcha (Always require captcha)

User Update

Using this API method, a relying party will be able to remotely update user profile fields supported by UUA

Input

Mandatory Fields:
  • current_email (required to uniquely identify the account being updated and resolve ambiguity in case of updates to the email address)
  • current_password (required to ensure user update is initiated only by the user and not by the relying party)
Optional Fields:
  • username
  • password
  • email
  • first_name
  • last_name

A sample input that updates all supported fields:

Output

If the input passes validation checks on all fields which are exactly the same as the validations performed when a user updates profile data on the UUA site.

If successful, the relying party receives the following data:

Depending on what fields were invalid, the error response will be a strict subset of the following:

Error messages that apply to all of the above fields and not mentioned above are:

  • This field is required

Restrictions

Any relying party with valid OAuth credential is able to attempt user update

Relying Party Responsibilities

The RP should do the following before calling UUA API for validation:

  • Check for minimum and maximum length of input. Values are provided below:

  • Check for unacceptable characters in input. Regular expression is provided below:

Operations on Website

Following remote operations are available to perform on Website objects

  • Retrieve website information
  • Create website
  • Update website

Retrieve website information

Input

Output

If successful, the relying party receives the following data:

If the URL is not valid, the RP receives the following data:

Restrictions

Retrieving website information is restricted in the following ways:

  • Website read requests on a specific website will be accepted only from an OAuth consumer that is connected to a UUA API administrator who owns the website

Relying party responsibilities

  • Check for minimum and maximum length of input

Create Website

Input

Mandatory fields:
  • name
  • url
Optional Fields:
  • is_active

Setting is_active to False will create the website but OAuth access will be disabled.

Output

If successful RP receives the following:

In case of failures, the RP will receive a strict subset of the following data:

Missing mandatory fields will return the additional message in their respective error lists:

  • This field is required

Restrictions

Retrieving website information is restricted in the following ways:

  • Website creation requests will be accepted only from an OAuth consumer that is connected to a UUA API administrator. The API administrator will become the owner of the created website

Relying party responsibilities

  • Check for minimum and maximum length of input

Update Website

Input

Mandatory fields:
  • current_url
Optional Fields:
  • name
  • url
  • is_active

A sample input that attempts to update all possible fields and resets OAuth credentials:

Output

If successful RP receives the following (Note the name change):

In case of failures, the RP will receive a strict subset of the following data:

Missing mandatory fields will return the additional message in their respective error lists:

  • This field is required

Restrictions

Retrieving website information is restricted in the following ways:

  • Website update requests for a specific website will be accepted only from an OAuth consumer that is connected to a UUA API administrator who owns that website

Relying party responsibilities

  • Check for minimum and maximum length of input

Piston Changes:

In order to make the API robust, Piston, the popular open source RESTful API package for django, was updated and is being used in PBS UUA API development.

The updated source is available on Github - PBS Education - django-piston

History

  • Original repository for Piston at BitBucket - jespern - django-piston was last updated over 9 months ago
  • A developer from Mozilla updated the source to make few important changes and put it on Github - mozilla - django-piston
  • PBS Education forked off the Mozilla fork as it seemed to have the desired changes over original and continued making improvements in our organization branch
  • There are no future releases planned for the original or Mozilla fork

Motivation/ Changes

There were a few important motivations behind the updates that PBS Education made to django-piston

Improved error handling:

  • We added the concept of detachable response classes to Piston, which allows implementors to choose from different formats of response. One could rely on the default Piston response, which returns flat data or strict HTTP responses.
  • One of the added response classes is EnhancedResponse. Enhanced response allows capturing and reporting of errors in case of HTTP 400 Bas Request. Technically django form errors fall under this category. Since Piston is django centric, we believe it should be able to spit back data validation errors along with a bad request response
  • We have added form validation exception handling in Piston and it automatically processes and sends back data validation error

Better error capturing:

  • Piston by default only allows return of HTTP responses via utility module rc
  • We added Exception classes for common HTTP response types that are handled automatically by Piston and captures information regarding the error that can be reported back to client depending on preferences in django settings
  • Allows better understanding of errors from client side

jsonp

  • We have added jsonp emitter support

OAuth Updates

  • django-piston unfortunately uses built-in OAuth module which is basically a modularized version of an outdated snapshot of Github - simplegeo - python-oauth2
  • Over time, python-oauth2 has been updated but Piston has been lagging behind
  • We have addressed issues with POST data handling per latest changes in python-oauth2

PUT/DELETE Issues

  • We have addressed issues with PUT/DELETE requests so that data sent over along with these requests are captured and is available for django forms to process

Output Data Formatting Support

  • Django model instances sent to Piston for processing and structuring data can be complex. We have added a Field class and View classes that handle processing of complex return data that not only extracts attributes from model instances but also from properties and functions defined in a model
  • No labels

2 Comments

  1. We need written policies for the following:

    • Check for minimum and maximum length of input
    • Check for unacceptable characters in input
    • Captcha
    1. I've added the basic policies around with these requirements.