4
1
Fork 0

backend-auth integration

pull/24/head
UnicodingUnicorn 2019-02-24 04:01:34 +08:00
parent d323083f74
commit 6b446d85d0
3 changed files with 79 additions and 76 deletions

View File

@ -23,7 +23,7 @@ Supply environment variables by either exporting them or editing ```.env```.
## API
Unless otherwise noted, bodies and responses are with ```Content-Type: application/json```.
Unless otherwise noted, bodies and responses are with `Content-Type: application/json`. Endpoints marked with a `*` require a populated `X-User-Claim` header from `backend-auth`.
| Contents |
| -------- |
@ -122,7 +122,7 @@ List of users.
### Get User
```
GET /user/:user
GET /user/id/:user
```
Get a specific user by ID.
@ -155,20 +155,14 @@ User object.
---
### Create Conversation
### Create Conversation*
```
POST /user/:user/conversation
POST /user/conversation
```
Create a new conversation for a user.
#### URL Params
| Name | Type | Description | Required |
| ---- | ---- | ----------- | -------- |
| user | String | User's ID. | ✓ |
#### Body
| Name | Type | Description | Required |
@ -190,16 +184,16 @@ Conversation object.
| Code | Description |
| ---- | ----------- |
| 400 | Error occurred parsing the supplied body. |
| 400 | Error occurred parsing the supplied body/Invalid `X-User-Claim` header |
| 404 | User with supplied ID could not be found in database. |
| 500 | Error occurred inserting entries into the database. |
---
### Delete Conversation
### Delete Conversation*
```
DELETE /user/:user/conversation/:conversation
DELETE /user/conversation/:conversation
```
Delete the specified conversation.
@ -208,7 +202,6 @@ Delete the specified conversation.
| Name | Type | Description | Required |
| ---- | ---- | ----------- | -------- |
| user | String | User's ID. | ✓ |
| conversation | String | Conversation's ID. | ✓ |
#### Success Response (200 OK)
@ -219,15 +212,16 @@ Empty body.
| Code | Description |
| ---- | ----------- |
| 400 | Invalid `X-User-Claim` header. |
| 404 | User/Conversation with supplied ID could not be found in database. |
| 500 | Error occurred deleting entries from the database. |
---
### Update Conversation
### Update Conversation*
```
PATCH /user/:user/conversation/:conversation
PATCH /user/conversation/:conversation
```
Update a conversation's details (mainly just title for now).
@ -236,7 +230,6 @@ Update a conversation's details (mainly just title for now).
| Name | Type | Description | Required |
| ---- | ---- | ----------- | -------- |
| user | String | User's ID. | ✓ |
| conversation | String | Conversation's ID. | ✓ |
#### Body
@ -253,26 +246,20 @@ Empty Body. (TODO: Updated conversation)
| Code | Description |
| ---- | ----------- |
| 400 | Error occurred parsing the supplied body. |
| 400 | Error occurred parsing the supplied body/Invalid `X-User-Claim` header. |
| 404 | User/Conversation with supplied ID could not be found in database. |
| 500 | Error occurred updating entries in the database. |
---
### Get Conversations
### Get Conversations*
```
GET /user/:user/conversation
GET /user/conversation
```
Get the conversations of the specified user.
#### URL Params
| Name | Type | Description | Required |
| ---- | ---- | ----------- | -------- |
| user | String | User's ID. | ✓ |
#### Success Response (200 OK)
List of conversations.
@ -291,14 +278,15 @@ List of conversations.
| Code | Description |
| ---- | ----------- |
| 400 | Invalid `X-User-Claim` header. |
| 500 | Error occurred updating entries in the database. |
---
### Get Conversation
### Get Conversation*
```
GET /user/:user/conversation/:conversation
GET /user/conversation/:conversation
```
Get a specific conversation of a specific user.
@ -307,7 +295,6 @@ Get a specific conversation of a specific user.
| Name | Type | Description | Required |
| ---- | ---- | ----------- | -------- |
| user | String | User's ID. | ✓ |
| conversation | String | Conversation's ID. | ✓ |
#### Success Response (200 OK)
@ -325,24 +312,24 @@ Conversation object.
| Code | Description |
| ---- | ----------- |
| 404 | User/Conversation with supplied ID could not be found in database. |
| 400 | Invalid `X-User-Claim` header. |
| 404 | Conversation with supplied ID could not be found in database. |
| 500 | Error occurred retrieving entries from the database. |
---
### Create Conversation Member
### Create Conversation Member*
```
POST /user/:user/conversation/:conversation/member
POST /user/conversation/:conversation/member
```
Add a member to the specified conversation of the specified member.
Add a member to the specified conversation.
#### URL Params
| Name | Type | Description | Required |
| ---- | ---- | ----------- | -------- |
| user | String | User's ID. | ✓ |
| conversation | String | Conversation's ID. | ✓ |
#### Body
@ -359,25 +346,24 @@ Empty body.
| Code | Description |
| ---- | ----------- |
| 400 | Error occurred parsing the supplied body/The length of the ID supplied in the body is less than 1. |
| 400 | Error occurred parsing the supplied body/The length of the ID supplied in the body is less than 1/Invalid `X-User-Claim` header. |
| 404 | User/Conversation with supplied ID could not be found in database. |
| 500 | Error occurred updating entries in the database. |
---
### Get Conversation Members
### Get Conversation Members*
```
GET /user/:user/conversation/:conversation/member
GET /user/conversation/:conversation/member
```
Get the members of the specified conversation of the specified member.
Get the members of the specified conversation.
#### URL Params
| Name | Type | Description | Required |
| ---- | ---- | ----------- | -------- |
| user | String | User's ID. | ✓ |
| conversation | String | Conversation's ID. | ✓ |
#### Success (200 OK)
@ -400,23 +386,18 @@ List of user objects in conversation.
| Code | Description |
| ---- | ----------- |
| 400 | Invalid `X-User-Claim` header. |
| 500 | Error occurred retrieving entries from the database. |
---
### Create Contact
### Create Contact*
```
POST /user/:user/contact
POST /user/contact
```
Add a new contact for the specified user.
#### URL Params
| Name | Type | Description | Required |
| ---- | ---- | ----------- | -------- |
| user | String | User's ID. | ✓ |
Add a new contact.
#### Body
@ -432,7 +413,7 @@ Empty body
| Code | Description |
| ---- | ----------- |
| 400 | Error occurred parsing the supplied body/The length of the ID supplied in the body is less than 1 or equal to the user's ID. |
| 400 | Error occurred parsing the supplied body/The length of the ID supplied in the body is less than 1 or equal to the user's ID/Invalid `X-User-Claim` header. |
| 500 | Error occurred updating entries in the database. |
---
@ -440,16 +421,10 @@ Empty body
### Get Contacts
```
GET /user/:user/contact
GET /user/contact
```
Get the contacts of the specified user.
#### URL Params
| Name | Type | Description | Required |
| ---- | ---- | ----------- | -------- |
| user | String | User's ID. | ✓ |
Get the user's contacts.
#### Success (200 OK)
@ -470,4 +445,5 @@ List of user objects in user's contacts.
| Code | Description |
| ---- | ----------- |
| 400 | Invalid `X-User-Claim` header. |
| 500 | Error occurred retrieving entries from the database. |

View File

@ -122,7 +122,7 @@ func (h *Handler) GetUser(w http.ResponseWriter, r *http.Request, p httprouter.P
func (h *Handler) CreateConversation(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
// Parse
userID := p.ByName("user")
userID := r.Context().Value("user").(string)
conversation := Conversation{}
decoder := json.NewDecoder(r.Body)
err := decoder.Decode(&conversation)
@ -175,7 +175,7 @@ func (h *Handler) CreateConversation(w http.ResponseWriter, r *http.Request, p h
func (h *Handler) GetConversations(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
// Parse
userID := p.ByName("user")
userID := r.Context().Value("user").(string)
// Response object
conversations := make([]Conversation, 0)
@ -211,7 +211,7 @@ func (h *Handler) GetConversations(w http.ResponseWriter, r *http.Request, p htt
func (h *Handler) GetConversation(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
// Parse
userID := p.ByName("user")
userID := r.Context().Value("user").(string)
conversationID := p.ByName("conversation")
// Response object
@ -241,7 +241,7 @@ func (h *Handler) GetConversation(w http.ResponseWriter, r *http.Request, p http
func (h *Handler) UpdateConversation(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
// Parse
userID := p.ByName("user")
userID := r.Context().Value("user").(string)
conversationID := p.ByName("conversation")
conversation := Conversation{}
decoder := json.NewDecoder(r.Body)
@ -286,7 +286,7 @@ func (h *Handler) UpdateConversation(w http.ResponseWriter, r *http.Request, p h
}
func (h *Handler) DeleteConversation(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
userID := p.ByName("user")
userID := r.Context().Value("user").(string)
conversationID := p.ByName("conversation")
// Delete
@ -342,7 +342,7 @@ func (h *Handler) DeleteConversation(w http.ResponseWriter, r *http.Request, p h
func (h *Handler) CreateConversationMember(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
// Parse
userID := p.ByName("user")
userID := r.Context().Value("user").(string)
conversationID := p.ByName("conversation")
member := User{}
decoder := json.NewDecoder(r.Body)
@ -396,7 +396,7 @@ func (h *Handler) CreateConversationMember(w http.ResponseWriter, r *http.Reques
func (h *Handler) GetConversationMembers(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
// Parse
userID := p.ByName("user")
userID := r.Context().Value("user").(string)
conversationID := p.ByName("conversation")
// Response object
@ -438,7 +438,7 @@ type PhoneNumber struct {
}
func (h *Handler) CreateContact(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
// Parse
userID := p.ByName("user")
userID := r.Context().Value("user").(string)
contact := PhoneNumber{}
decoder := json.NewDecoder(r.Body)
err := decoder.Decode(&contact)
@ -490,7 +490,7 @@ func (h *Handler) CreateContact(w http.ResponseWriter, r *http.Request, p httpro
func (h *Handler) GetContacts(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
// Parse
userID := p.ByName("user")
userID := r.Context().Value("user").(string)
// Response object
contacts := make([]User, 0)

47
main.go
View File

@ -1,7 +1,9 @@
package main
import (
"context"
"database/sql"
"encoding/json"
"log"
"net/http"
"os"
@ -39,25 +41,25 @@ func main() {
// Users
router.POST("/user/", h.CreateUser)
router.GET("/user/", h.GetUsersByPhone)
router.GET("/user/:user", h.GetUser)
router.GET("/user/id/:user", h.GetUser)
//router.PATCH("/user/:user", h.UpdateUser)
// Conversations
router.POST("/user/:user/conversation/", h.CreateConversation)
router.GET("/user/:user/conversation/", h.GetConversations) // USER MEMBER CONVERSATION
router.DELETE("/user/:user/conversation/:conversation", h.DeleteConversation)
router.POST("/user/conversation/", AuthMiddleware(h.CreateConversation))
router.GET("/user/conversation/", AuthMiddleware(h.GetConversations)) // USER MEMBER CONVERSATION
router.DELETE("/user/conversation/:conversation", AuthMiddleware(h.DeleteConversation))
//router.GET("/user/:user/conversation/bymembers/", h.GetConversationsByMembers) // TODO
router.GET("/user/:user/conversation/:conversation", h.GetConversation) // USER MEMBER CONVERSATION
router.PATCH("/user/:user/conversation/:conversation", h.UpdateConversation) // USER MEMBER CONVERSATION ADMIN=true -> update conversation title
router.GET("/user/conversation/:conversation", AuthMiddleware(h.GetConversation)) // USER MEMBER CONVERSATION
router.PATCH("/user/conversation/:conversation", AuthMiddleware(h.UpdateConversation)) // USER MEMBER CONVERSATION ADMIN=true -> update conversation title
//router.DELETE("/user/:user/conversation/:conversation", h.DeleteConversation) // USER MEMBER CONVERSATION -> delete membership
router.POST("/user/:user/conversation/:conversation/member/", h.CreateConversationMember) // USER MEMBER CONVERSATION ADMIN=true -> create new membership
router.GET("/user/:user/conversation/:conversation/member/", h.GetConversationMembers) // USER MEMBER CONVERSATION
router.POST("/user/conversation/:conversation/member/", AuthMiddleware(h.CreateConversationMember)) // USER MEMBER CONVERSATION ADMIN=true -> create new membership
router.GET("/user/conversation/:conversation/member/", AuthMiddleware(h.GetConversationMembers)) // USER MEMBER CONVERSATION
//router.DELETE("/user/:user/conversation/:conversation/member/:member", h.DeleteConversationMember) // USER MEMBER CONVERSATION ADMIN=true -> delete membership
// Last heard
//router.GET("/user/:user/lastheard/:conversation", h.GetLastheard)
//router.PUT("/user/:user/lastheard/:conversation", h.SetLastheard)
// Contacts
router.POST("/user/:user/contact/", h.CreateContact)
router.GET("/user/:user/contact/", h.GetContacts)
router.POST("/user/contact/", AuthMiddleware(h.CreateContact))
router.GET("/user/contact/", AuthMiddleware(h.GetContacts))
//router.GET("/user/:user/contact/:contact", h.GetContact)
//router.DELETE("/user/:user/contact/:contact", h.DeleteContact)
//router.GET("/user/:user/contact/:contact/conversation/", h.GetContactConversations)
@ -65,3 +67,28 @@ func main() {
log.Printf("starting server on %s", listen)
log.Fatal(http.ListenAndServe(listen, router))
}
type RawClient struct {
UserId string `json:"userid"`
ClientId string `json:"clientid"`
}
func AuthMiddleware(next httprouter.Handle) httprouter.Handle {
return func (w http.ResponseWriter, r *http.Request, p httprouter.Params) {
ua := r.Header.Get("X-User-Claim")
if ua == "" {
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
return
}
var client RawClient
err := json.Unmarshal([]byte(ua), &client)
if err != nil {
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
return
}
context := context.WithValue(r.Context(), "user", client.UserId)
next(w, r.WithContext(context), p)
}
}