-
Notifications
You must be signed in to change notification settings - Fork 5
LCS API Endpoints
This is an endpoint-by-endpoint listing of the LCS API with the parameters, details, and kinks written out.
Don't read this unless you have a specific question. Read the more general docs for a higher-level overview. The general ideas include something like a table of contents.
The error messages below are imprecise on dev (the dev and prod are slightly mismatched). The status codes are accurate and should be the only thing you use to check for an error condition - messages are intended for programmers, not the code.
Method: POST
Data: JSON
Example JSON:
{
"auth_email": "email of the person checking people in",
"token": "token belonging to auth_email",
"qr": "qr of the person attending the event. (email or id)",
"event": "name of the event being attended",
"again": "optional. whether or not to allow attending an event twice"
}
Returns:
Situation | Value | HTTP Code | Type |
---|---|---|---|
success | {"email": "email matched", "new_count": 0 /*amount of times the event was attended*/} |
200 | application/json |
user already attended. use "again": true to ignore |
user already checked into event |
402 | text/plain |
user or qr not found | user not found |
404 | text/plain |
Method: POST.
Data: JSON.
Example JSON:
{
"email": "somebody@somewhere.com",
"password": "the plain text password"
}
Returns:
Situation | Value | HTTP Code | Type |
---|---|---|---|
Email or password not present in JSON. | Invalid Request |
400 | Text/plain |
No user with that email and password. | invalid email,hash combo |
403 | Text/plain |
The user is present, but used MLH. | Please use MLH to log in. |
403 | Text/plain |
The user is present, but the password does not match. | invalid email,hash combo |
403 | Text/plain |
Successful login | {"auth": { "token": "some token", "valid_until": "ISO date for 3 days from now", "email": "the email passed in"}} |
200 | Application/JSON |
Notes: The password is hashed in the processing - plain text is not in the DB. For security, however, you must use HTTPS so that user passwords cannot be intercepted.
Method: POST.
Data: JSON.
Example JSON:
Minimal:
{
"email": "some_email@some_site.com",
"password": "the plain text password"
}
With a magic link:
{
"email": "some_email@some_site.com",
"link": "bibaty bobity boo",
"password": "the plain text password"
}
Maximal:
{
"email": "some_email@some_site.com",
"password": "the plain text password"
"github": "Their github",
"major": "Their major",
"short_answer": "Their short answer",
"shirt_size": "Their shirt size",
"first_name": "Their first name",
"last_name": "Their last name",
"dietary_restrictions": "Their dietary restrictions",
"special_needs": "Their special needs",
"date_of_birth": "Their date of birth",
"school": "Their school",
"grad_year": "Their grad year",
"gender": "Their gender",
"registration_status": "Their registration status",
"level_of_study": "Their level of study",
"slack_id": "Their unique slack id"
}
Returns:
Situation | Value | HTTP Code | Type |
---|---|---|---|
Registration is closed | Registration is closed |
400 | Text/plain |
The email is invalid | An error message explaining the email troubles. | 400 | Text/plain |
No email | No email provided! |
400 | Text/plain |
No password provided. | No password provided |
400 | Text/plain |
The email is already in the DB | Duplicate user! |
400 | Text/plain |
Successful login | {"auth": { "token": "some token", "valid_until": "ISO date for 3 days from now", "email": "the email passed in"}} |
200 | Application/JSON |
The magic link can be optimally provided to consume a link on creation. This is convenient for some magiclinks. See the consume endpoint which is wholly subsumed by this.
Method: POST
Data: JSON
Example JSON:
{
"email": "somebody@somewhere.com",
"token": "the authentication token string"
}
Returns:
Situation | Value | HTTP Code | Type |
---|---|---|---|
Invalid data submission | Data not submitted |
400 | Text/plain |
User email not found | Email not found |
403 | Text/plain |
User token expired | Invalid token |
403 | Text/plain |
Success | The data submitted | 200 | Application/JSON |
Method: POST
Data: JSON
Example JSON:
{
updates : {'$set': {'grad_year': 2020}},
user_email: "somehacker@email_server.thing",
auth_email: "somehacker@email_server.thing",
auth: "the auth token"
}
This changes the Graduation year of the hacker (with email somehacker@your_hackathon.org
)
to 2020
(assuming the auth token is valid).
{
updates : {'$set': {'registration_status': 'checked-in'}},
user_email: "somehacker@email_server.thing",
auth_email: "some_admin_email@your_hackathon.org",
auth: "the auth token"
}
This changes the registration status of the user somehacker@your_hackathon.org
if the
user (admin - that is director or organizer) is some_admin_email@your_hackathon.org
and the token
is valid for the admin. We discuss the details of the permissions where we discuss the user object.
{
updates : {'$set': {'day_of.checkIn': True, 'registration_status': 'checked-in'}},
user_email: "somehacker@email_server.thing",
auth_email: "some_admin_email@your_hackathon.org",
auth: "the auth token"
}
Assuming the validity of the auth token and that auth_email
is an organizer, this is the update
an app should use when scanning a QR code to admit a hacker into the hackathon.
$set
against the day_of
with fields that do not yet exist are simply added in. This is a convenience
so that LCS does not need to be updated every time there is a new event that needs to be tracked.
{
updates : {'$inc': {'day_of.lunch1': 1}},
user_email: "somehacker@email_server.thing",
auth_email: "some_admin_email@your_hackathon.org",
auth: "the auth token"
}
This update would be performed when a user is scanned for lunch on Saturday. Lunch is the only meal that occurs
twice and tends to be numbered, 1 being the Saturday one and 2 the one on Sunday. $inc
increments since the food
team may allow hackers to receive multiple servings. If the field is not there, MongoDB will set it to the value
given (so, in this case 1, if it's the hacker's first time having lunch on Saturday).
Auth email vs. user email: In order to prevent users from updating their own status or letting any sort of malicious changes to a hacker's data, we distinguish updates between those allowed for admins and those allowed for hackers. The "auth email" is the email of the person performing the updates and the "user email" is the email of the user being updated.
Mongo docs (what $set
is about): So this endpoint actually allows for any individual update (uniquely determining who to update by email).
So we differ to Mongo to explain the operations you can put..
Most fields are all or nothing: if you can update the field, you can do anything to it. The only exception is the registration status
which has its own FSM that determines update permissions.
Silent failures: If the change is not permitted by a validation issue, the endpoint silently does not change the field in question. Every field is considered separately - so if an update is more advanced, it may only partially go through. Check the user object for details on whether the hacker can update the status or if an admin is needed.
Returns:
Situation | Value | HTTP Code | Type |
---|---|---|---|
Email, auth email or token (auth) not given | Data not submitted. |
400 | Text/plain |
Auth email is not found | Auth email not found. |
400 | Text/plain |
Auth token is not found | Authentication token not found. |
400 | Text/plain |
Auth email is not the hacker email and is not that of an admin | Permission Denied |
403 | Text/plain |
Hacker email not found | User email not found |
400 | Text/plain |
Success | Successful Request |
200 | Text/plain |
Method: POST
Data: JSON
Example JSON:
{
link: 'the randomly generated magic link',
email: 'hacker@email.thing',
token: 'the auth token'
}
More on the use: Remember to see the general docs for how this interacts with the other endpoints to create its own updating system.
Returns:
Situation | Value | HTTP Code | Type |
---|---|---|---|
link not given | No magic link provided |
400 | Text/plain |
link not found | Invalid magiclink |
400 | Text/plain |
The user is an MLH user (so we do not have control over their password) | Please change your password through MLH |
400 | Text/plain |
The user email is not found | We could not find that email |
400 | Text/plain |
A login issue occurred in handling the link (for a role update) | Failed to update: please login again. |
400 | Text/plain |
Password has been updated | Successfully updated your password |
200 | Text/plain |
Role has been updated | Successfully updated your role |
200 | Text/plain |
Method: POST
Data: JSON
Example JSON:
For a forgotten password:
{
email: "some@email.thing,
forgot: true
}
and to promote users:
{
email: "some_director@your.hackathon",
"token": "the user's token",
"numLinks": 3,
"permissions": ["director", "judge", "organizer", "volunteer", "mentor"],
"emailsTo": ["first_to_promote@their_email.com", "second_to_promote@their_email.com", "third_to_promote@their_email.com"]
}
The numLinks
parameter is optional - 1 by default. The emailsTo
is necessary to email the promoted users so that they may be promoted.
More on the use: Remember to see the general docs for how this interacts with the other endpoints to create its own updating system. Also note that admins and hackers have very different uses: hackers may only request a password reset while admins may promote anybody. Additionally, there is no verification of the email being promoted and if that email is already that of a hacker.
Returns:
Situation | Value | HTTP Code | Type |
---|---|---|---|
Valid forgotten password case | Forgot password link has been emailed to you |
200 | Text/plain |
The user is an MLH user - we don't have their password | Please use MLH to login. |
400 | Text/plain |
The user is not a user - they must create an account | Invalid email: please create an account. |
400 | Text/plain |
The admin user did not provide enough information for the link | You forgot some params try a again |
400 | Text/plain |
The admin user was not enough of an admin | Invalid permissions |
400 | Text/plain |
The admin user could not be logged in | Please input a proper auth token |
400 | Text/plain |
Valid director link case | List of magic link objects - see below. | 200 | Application/JSON |
The magic link object:
{
"permissions": ["director", "judge", "organizer", "volunteer", "mentor"]
"email": "someuser@your_hackathon.org"
"forgot": false,
"link": "a hashy boi",
"valid_until": "UTC time now + 3 hours"
}
Method: GET
Data: JSON
Example Uses: Just a plain ol' GET:
GET http://your-deploy.execute.amazonaws.com/dayof-events
You can pass a num_events
to influence the number of events shown (defaults to 10).
Returns:
Situation | Value | HTTP Code | Type |
---|---|---|---|
The calendar API is misconfigured | Please interactively generate client secret file. |
400 | Text/plain |
The calendar API returned an error | Unable to get events. |
400 | Text/plain |
Success | Google API events. The events are returned as specified by google. | 200 | Application/JSON |
Method: GET
Data: JSON
Example Uses: Just a plain ol' GET:
GET http://your-deploy.execute.amazonaws.com/dayof-slack
You can pass a num_events
to influence the number of events shown (defaults to 10).
Returns:
Situation | Value | HTTP Code | Type |
---|---|---|---|
The slack API returned an error | Unable to retrieve messages |
400 | Text/plain |
The slack API returned no messages | No messages found. |
400 | Text/plain |
Success | Slack messages that are not "join" messages. The messages are returned as specified by slack. | 200 | Application/JSON |
Method: POST
Data: JSON
Example JSON:
A user emailing themselves:
{
"template": "some sparkpost template",
"recipients": ["some_email@your.hackathon"],
"email": "some_email@your.hackathon",
"token": "some hashy boi"
}
A user (director) emailing two people:
{
"template": "some sparkpost template",
"recipients": ["some_email@your.hackathon", "some_other_email@your.hackathon"],
"email": "some_director@your.hackathon",
"token": "some hashy boi"
}
A user (director) emailing by a query (are they a judge):
{
"template": "some sparkpost template",
"query": {'role.judge': true}
"email": "some_director@your.hackathon",
"token": "some hashy boi"
}
A user (director) emailing people with personalised links:
{
"template": "some sparkpost template",
"recipients": ["some_email@your.hackathon", "some_other_email@your.hackathon"],
"links": ["https://your-hackathon.org/link-1", "https://your-hackathon.org/link-2"],
"email": "some_director@your.hackathon",
"token": "some hashy boi"
}
Constraints: The query or a list of recipients that is not just the user's email itself can be submitted by directors only.
Additionally, links
can only be provided with recipients. This is since the number of results in a query cannot be known, so the correct
number of links would likely not be provided.
Returns: There are 4 classes of errors and the messages are rather self-explanatory:
- An issue with the invocation: either missing data or lacking permission. Note that users may only email themselves, directors can email anybody. An empty list of recipients is caught here too.
- An issue with sparkpost: invalid templates, or any sort of malarchy. The error string will be from sparkpost except in deeply pathological cases.
- An issue with the query: if the user passes in a query, it might have an issue which will be reported.
- An issue with personalised links.
Method: POST
Data: JSON
Example JSON:
{
"auth_email": "email of the user doing the link",
"token": "one hashy boi",
"email": "the hacker being linked",
"qr_code": "value of a qr. an email or id string"
}
Returns:
Situation | Value | HTTP Code | Type |
---|---|---|---|
success | success |
200 | text/plain |
not authorized. or bad role | permission denied |
403 | text/plain |
user not found | user not found |
404 | text/plain |
Method: POST
Data: JSON
Example JSON:
There could be a user:
{
"email": "users_email@your_hackathon",
"token": "some hashy boi",
"query": {"email": "their email"}
}
and then they can aggregate (counting the shirt sizes and genders):
{
"email": "users_email@your_hackathon",
"token": "some hashy boi",
"query": ["shirt-size", "gender"],
"aggregate": true
}
and there may not even be a user:
{
"query": ["shirt-size", "gender"],
"aggregate": true,
"just_here": true
}
Returns
The old validation rules were clumsy at best. There are three types of queries, explained in decreasing power:
- A director query: directors are allowed to run any query. We only ensure that non-serializable Mongo stuff is not included.
- A user query: users can get themselves (only). (So the validate endpoint is good enough.) Redacts reimbursement information on hackers who aren't confirmed.
- A non-director aggregation: anybody (regardless of relation to LCS) can aggregate by the powerset of these fields:
major
,shirt_size
,dietary_restrictions
,school
,grad_year
,gender
,level_of_study
,ethnicity
. This will create counts of every combination of the field values found in the database. Thejust_here
field is a flag on whether to exclude non-checked in users.
Method: POST
Data: JSON
Example JSON:
{
"email": "users_email@your_hackathon",
"token": "some hashy boi",
}
Returns
- send resume to s3 by doing a
PUT
request to the upload urlContent-Type
header must be set toapplication/pdf
. - get resume from s3 by doing a
GET
request to the upload url. - if we have the resume exists will be true.
{
"upload": "url",
"download": "url",
"exists": true|false,
}
Method: POST
Data: JSON
Example JSON:
{
"email": "director@place.com",
"token": "hashy boi"
}
Returns
Mostly changes the DB to include reimbursement estimates to travelling users. Uses the google distance matrix API and configurable cost-per-mile constants.
The error messages are generated by the various libraries and APIs: there can be google maps API errors, Mongo query errors, and errors in the JSON sent in. Only directors can call the API. On success, the write operation result and the amount spent are returned in JSON. For example:
{"statusCode": 200, "mongo_result": 60, "total": 3000}
Method: POST
Data: JSON
Example JSON:
{
"email": "director@place.com",
"token": "hashy boi",
"other_email": "hacker@hackathon.com"
}
Returns
Situation | Value | HTTP Code | Type |
---|---|---|---|
Email not found in LCS | User Not Found |
403 | Text/plain |
Auth token is invalid | Token invalid |
403 | Text/plain |
Other email not found in LCS | Other user not found within LCS |
403 | Text/plain |
Slack API token missing | Slack API token not configured |
503 | Text/plain |
Slack id of one or both users not in LCS | Slack ID not present within LCS for the given user(s) |
403 | Text/plain |
Slack API request error | Encountered a Slack API error |
503 | Text/plain |
Slack API error (related to users) |
There was an error with the user id's provided: {error_str} The error_str is directly from the Slack API endpoint
|
403 | Text/plain |
Slack API error (general) |
Encountered a slack API error: {error_str} The error_str is directly from the Slack API endpoint
|
503 | Text/plain |
Success | Slack dm link object (below) |
200 | Application/JSON |
A slack dm link object:
{"statusCode": 200, "slack_dm_link": "url"}
Method: POST
Data: JSON
Example JSON:
{
"email": "users_email@your_hackathon",
"token": "some hashy boi",
}
Returns
- send waiver to s3 by doing a
PUT
request to the upload urlContent-Type
header must be set toapplication/pdf
. - get waiver from s3 by doing a
GET
request to the upload url. - if we have the waiver exists will be true.
{
"upload": "url",
"download": "url",
"exists": true|false,
}
For Users
For Current Implementors
Old Deployment Information