.. | ||
authserver | ||
media | ||
.gitignore | ||
manage.py | ||
parselog_example.py | ||
README.md | ||
requirements.txt |
Protospace lockout authorization server
Provides an API to the web client and web server to serve tool data and authenticate users on tools.
Setup
Initial run
$ sudo apt install python3 python3-pip python-virtualenv python3-virtualenv # for Debian
$ virtualenv -p python3 env
$ . env/bin/activate
(env) $ pip install -r requirements.txt
(env) $ python manage.py migrate --run-syncdb
(env) $ python manage.py createsuperuser --email admin@example.com --username admin
(env) $ python manage.py runserver
Authenticate a Protospace login using the curl
command below against your server, then navigate to http://127.0.0.1:8000/admin/ and login with the superuser account you just created above.
Once logged in, navigate to "Profiles" and make your Protospace user a lockout admin.
Now you have total control of the system and can make other users lockout admins though the API or web interface.
Supervisor
Supervisor is used to keep the script always running.
$ sudo apt install supervisor
Create a file named /etc/supervisor/conf.d/authserver.conf and add:
[program:authserver]
user=tanner
directory=/opt/pslockout/pslockout/authserver
command=/bin/bash -c 'source env/bin/activate && python manage.py runserver 0.0.0.0:8000'
autostart=true
autorestart=true
stderr_logfile=/var/log/authserver.log
stderr_logfile_maxbytes=1MB
stdout_logfile=/var/log/authserver.log
stdout_logfile_maxbytes=1MB
API
The API is RESTful and returns hyperlinked json data. URLs require a trailing slash.
It's also possible to interact with the API through a web interface at http://tools-auth.protospace.ca from the Protospace LAN. Any Protospace users that have already authenticated through /login/ are able to login.
Authentication
Authentication is token-based and done against the Protospace member portal. Upon successful login, the auth server will automatically register the user and create them a profile.
POST /login/
POST data username
and password
. Upon successful login, a 200 status and a token will be returned.
Example request:
curl -d username=tanner.collin -d password=supersecret http://tools-auth.protospace.ca/login/
Example response:
{
"token": "9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b"
}
In subsequent requests, the token key should be included in the Authorization
HTTP header. The key should be prefixed by the string literal "Token", with whitespace separating the two strings. For example:
Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b
Example authenticated request:
curl -H "Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b" http://tools-auth.protospace.ca/user/
For anonymous users
GET /tooldata/
Returns all the info about the shop and its tools. Tools are split into categories.
Example response:
{
"categories": [
{
"url": "http://tools-auth.protospace.ca/category/wood-shop/",
"tools": [
{
"url": "http://tools-auth.protospace.ca/tool/table-saw/",
"category": "http://tools-auth.protospace.ca/category/wood-shop/",
"firmware": "0010",
"upgrade_group": "Critical",
"name": "Table Saw",
"slug": "table-saw",
"info": "scary tool",
"wiki_id": 123,
"photo": "http://tools-auth.protospace.ca/media/DSC00125.jpg",
"mac": "2C3AE843A15F"
},
{
"url": "http://tools-auth.protospace.ca/tool/jointer/",
"category": "http://tools-auth.protospace.ca/category/wood-shop/",
"firmware": "0010",
"upgrade_group": "Testing",
"name": "Jointer",
"slug": "jointer",
"info": "goes buzz buzz",
"wiki_id": 1,
"photo": "http://tools-auth.protospace.ca/media/uq4ldzsp4bu01.jpg",
"mac": "2C3AE8439EAD"
}
],
"name": "Wood Shop",
"slug": "wood-shop",
"info": "protospace wood shop",
"photo": "http://tools-auth.protospace.ca/media/ps-wood-shop.jpg"
},
{
"url": "http://tools-auth.protospace.ca/category/metal-shop/",
"tools": [
{
"url": "http://tools-auth.protospace.ca/tool/metal-lathe/",
"category": "http://tools-auth.protospace.ca/category/metal-shop/",
"firmware": "0010",
"upgrade_group": "Critical",
"name": "Metal Lathe",
"slug": "metal-lathe",
"info": "spins fast",
"wiki_id": 42,
"photo": "http://tools-auth.protospace.ca/media/lathe.jpeg",
"mac": "ABCDEF000003"
}
],
"name": "Metal Shop",
"slug": "metal-shop",
"info": "protospace metal shop",
"photo": "http://tools-auth.protospace.ca/media/metal-shop02.jpg"
}
]
}
GET /cards/[MAC]/
Returns all card numbers authorized to use a machine based on MAC address.
Card numbers are on one line separated by a comma.
Example request:
curl http://tools-auth.protospace.ca/cards/2C3AE843A15F/
Example response:
"00000B8567,00000A4123,00000C9999"
POST /infolog/[MAC]/
Send log entries to the auth server for logging. Entries are base64 encoded in the log
param.
Returns the number of entries processed, the current server unix time, and the firmware version for that lockout.
Example request:
curl -d log=cHJldGVuZCB0aGF0IHRoZXNlIGFyZSBhY3R1YWwgbG9nIGVudHJpZXMgYW5kIHJhbmRvbSB0ZXh0 http://tools-auth.protospace.ca/infolog/2C3AE843A15F/
Example response:
{
"processed": 7,
"version": "MRWIZARD 0010 MRWIZARD",
"unixTime": 1551139854
}
GET /update/[MAC]/
Returns the current firmware binary that should be running on the lockout.
Example request:
curl http://tools-auth.protospace.ca/update/2C3AE843A15F/
For authenticated users
GET /user/
Returns info about the logged in user, including which tools they are authorized on. Note the top-level array (a quirk of django-rest-framework).
Example response:
[
{
"username": "tanner.collin",
"profile": {
"url": "http://tools-auth.protospace.ca/profile/2/",
"user": "tanner.collin",
"card": "00000A4123",
"authorized_tools": [
"table-saw",
"jointer"
],
"lockout_admin": true
}
}
]
PUT /select-courses/
Send a list of course slugs that the user has taken in the courses
param separated by a comma.
This allows users to declare which courses they have taken the first time they log into the lockout website (honour system).
Operation can only be done once. Returns the number of courses added.
Example request:
curl -X PUT -H "Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b" -d courses=wood-1,wood-2,metal-mig http://tools-auth.protospace.ca/select-courses/
Example response:
{"updated":3}
For lockout admins
Ensure images are square and 1280x1280 px large. Slugs should be lowercase and one word (replace spaces with hyphens).
GET, POST /tool/
Get a list of tools, or post a new tool to the database.
GET, PUT, DELETE /tool/[slug]/
Get a specific tool, modify or delete an existing one.
GET, POST /category/
Get a list of categories, or post a new category to the database.
GET, PUT, DELETE /category/[slug]/
Get a specific category, modify or delete an existing one.
Note: you can only delete a category that has no tools.
GET, POST /course/
Get a list of courses, or post a new course to the database.
GET, PUT, DELETE /course/[slug]/
Get a specific course, modify or delete an existing one.
GET /profile/
Get a list of all profiles.
GET, PUT /profile/[id]/
Get a specific profile, or modify an existing one.
Here you can authorize users on tools or make them another lockout admin.
GET, POST /firmware/
Get a version of the firmware, or post a new one to the database.
Select which group of tools to deploy the new firmware version to, then upload a firmware .bin file. The version number is extracted from the binary data and must be unique.
Updating firmware objects is not allowed. To assign a new tool to a firmware version, go through the tool object.
PUT /update-cards/
Send a dictionary of username=card_number,card_number,card_number pairs to update any profiles already in the system. Users not already registered will be ignored.
Responds with the number of profiles updated.
Operation is idempotent.
Example PUT data:
{
"tanner.collin": "00000A4123,00000A4124,00000A4125",
"matthew.mulrooney": "00000B8567",
"not-a-member": "539830843A"
}
Example response:
{"updated":2}
Example request:
curl -X PUT -H "Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b" -d tanner.collin=00000A4123,00000A4124 -d matthew.mulrooney=00000B8567 http://tools-auth.protospace.ca/update-cards/