Base on MoSCoW principle. Must haves and should haves are planned to be worked on.
- Features/issues marked with plus (+) are implemented/solved.
- Features/issues marked with minus (-) are yet to be implemented.
- Class based views validation decorator.
- Extend the Django app with authentication backend for logging into Django with tokens generated by ska.
- For auth backend, add models for tracking of the used tokens. Add management commands for purging the tracking data.
- Demo (quick installer) for Django app.
- Populate foo model data in demo app.
- Make it easy to add additional data (such as user data, for auth backend) to the URL. Sign additional data (affect the signature hash) when providing extra params. In that case, provider (see later on) would be just one of those; NOTE, that it shall be a reserved "term").
- In Django app, allow multiple secret keys (add param provider, which would contain a UID of the provider and would be as well embed into the signature). Based on the UID, locally an appropriate provider would be picked. The default secret_key would stay intact.
- Allow to define a custom callback per provider.
- Log errors of authentication backend.
- In the validation result, in addition to reason and result properties, add error_codes property, which is basically a list of codes. Define the codes in some separate module or in constants, so that it's possible to determine (if desired) which case are we dealing with.
- Make it possible to use other algorithms, than HMAC. Implement an abstract Signature class. Leave the HMAC SHA-1 as a default, but make it possible to provide a custom one or even a self defined hash algorithm.
- Update the documentation and add code comments reflecting the hash algorithm changes.
- Add tests for various hash algorithms.
- Add tests for Django auth backend.
- Make a django template tag module for signing urls. The concept of signing should be based on providing an existing RequestHelper for handling the URL signing or making a RequestHelper in the template context and reusing it for signing URLs.
- Make it possible to encrypt the URL values (so that they are not exposed plain-text, but rather use some encryption method, which is possible to decrypt.
- Better documentation for ska.contrib.django.ska module.
- Make sure (perform a check), that given request variables do not overlap with reserved words: auth_user, valid_until, signature, extra.
- Find and implement the best way of making ska timezone aware. Likely,
reserve another keyword for it and pass in
extra
argument on the sender side. On the recipient side, if present - use when validating. - Add provider, first_name, last_name, email to the Django constants module.
- Update the tests (mkdirs) so that database creation for Django ska app works smoothly.
- Additional security measures (like browser info embed into signature). If browser changed, it becomes invalid.
- Add browser info to the token (auth backend).
- Plone app for logging into Plone with tokens generated by ska ( in-development).
We provide a dictionary with data, that should be embed into the URL to the sign_url function. Imagine, that some request requires more data to be sent (like username or email), which we would want to use in the end.
Thus, we really provide an extra dictionary with data, that should be sent embed into the URL.
In order to validate the request on the endpoint (because, the original URL could contain some more data), we need to generate a list of additional fields, added by the package. We know already about the auth_user, signature and valid_until, but additional data, that was embed into the signature, should be listed in the extra request param in the following way: names of params should be comma separated. In order to avoid faking the data, the hash should be made of entire data in the following way:
- Additional data dict, would be sorted by keys.
- We would iterate through the dictionary and make a string of it.
- Then we would append the string to the
get_base
method and it would be hashed.
sign_url(
auth_user='user',
secret_key='your-secret_key',
url='http://e.com/api/',
extra={
'email': 'doe@example.com',
'last_name': 'Doe',
'first_name': 'Joe',
}
)
And finally, instead of this:
http://e.com/api/?valid_until=1378.0&auth_user=user&signature=YlZ
We would get this:
http://e.com/api/?valid_until=1378.0&auth_user=user&signature=YlZ&first_name=John&last_name=Doe& email=doe@example.com&age=64&gender=male&extra=email,first_name,last_name
When validating a request, we would read the contents of the extra
param,
and assembled the original data, that was used to generate the signature.
The rest of data (age, gender), which was not a part of the signed data, is
not interesting. We would read the extra
param (if exists), assembled a
dictionary, create base of it and go on matching the hash in the very same
way we did before.
When validating the request, we would do as follows.
validation_result = validate_signed_request_data(
request.REQUEST,
secret_key='your-secret_key'
)