Closed Bug 1130765 Opened 8 years ago Closed 8 years ago

[alerts] create authenticated get/post api for alerts


(Input Graveyard :: Backend, defect, P1)



(Not tracked)



(Reporter: willkg, Assigned: willkg)



(Whiteboard: u=analyzer c=alerts p=3 s=input.2015q1)

The Alerts system will be populated by emitters which can be scripts and other systems. The emitters will POST new alerts to Input using an API endpoint. The API endpoint will require HTTPS and authentication in order to post.


* we should use something built in to Django REST Framework
* authentication things are used by emitters--not users--so we probably shouldn't tie them to user accounts
* we need a way to easily create and revoke authentication credentials

This bug covers figuring out a plan and then implementing the plan, tests and documentation.
Before working on this, I looked into whether we should upgrade to django-rest-framework 3.0. There's a lot of API changes between the version we're using and 3.0. Seems pretty daunting. I think I'll push it off until later. That's in bug #1132455.

Meanwhile, I'll try to do a simple implementation here that will (hopefully) be easy to change when we upgrade.

Anyhow, grabbing this to work on now.
Assignee: nobody → willkg
I'm implementing a token-based API. The Django admin will generate tokens. An emitter will use a token when emitting new alerts (aka POSTing to the API). The token will permit the emitter to emit alerts for specific alert flavors (and no other flavors).

For now, we'll use the Django admin to administrate all this since it's pretty minimal maintenance-wise. At some point we might want to write a separate maintenance thing for the analyzer area.

We're not going with standard Django users/permissions and the DRF API token system because I don't want to conflate emitters with Django users. While we'd get the minor convenience of not having to roll our own for everything, we're not talking about a lot of code here and the conflation of Django users with emitters and then having to add an object-level permission system ends up being equivalent-ish in the amount of work required.

Anyhow, I've got tokens and token creation implemented. I'll probably have this finished up next week.
Token authentication is working. There's an admin screen that lets us create, edit and disable tokens. Lots of tests. The token system is not tied to the alerts system, so we can use it elsewhere as well.

Tokens are specified with an HTTP header in API requests. For example:

    Authorization: token cd64de0e6c4c491f90fe1d362104c1e5

Alert flavors have a list of tokens that are permitted to GET and POST alerts of that flavor. We also handle disabled flavors, invalid tokens, improperly formatted tokens, etc.
Whiteboard: u=analyzer c=alerts p= s=input.2015q1 → u=analyzer c=alerts p=2 s=input.2015q1
After talking to Mike and Ricky about the api endpoints, I decided we should rework them.

So the new GET endpoint:

    GET /api/v1/alerts/alert/

And you'd specify filters:


If your token is not permitted for a specified flavor, you'll get back an error. Otherwise, it'll do a query for alerts of those flavors.

The new POST endpoint:

    POST /api/v1/alerts/flavor/<flavor>/addalert

The idea here is that you're operating on the flavor and creating a new alert for it. This is more flexible since it allows us to operate on other models and also do different operations other than "addalert".

It makes the urls a little more goofy especially since there isn't much else you can do here, but this bakes in a lot more flexibility which is probably helpful at this point since we don't really know what the future involves and these changes are easy to implement.

Will update the PR today.
Finished updating the PR.
Talked about API endpoints some more and changed the POST endpoint to be the same as the GET endpoint. ONE ENDPOINT TO RULE THEM ALL!

Landed in master:

Will push after dinner and link to the docs.
Pushed to prod just now.

Documentation is here:
Closed: 8 years ago
Resolution: --- → FIXED
Whiteboard: u=analyzer c=alerts p=2 s=input.2015q1 → u=analyzer c=alerts p=3 s=input.2015q1
Product: Input → Input Graveyard
You need to log in before you can comment on or make changes to this bug.