From 6b446d85d0bae4c19eb6364c65b9e7fea4ee4197 Mon Sep 17 00:00:00 2001 From: UnicodingUnicorn <7555ic@gmail.com> Date: Sun, 24 Feb 2019 04:01:34 +0800 Subject: [PATCH] backend-auth integration --- README.md | 90 ++++++++++++++++++++--------------------------------- handlers.go | 18 +++++------ main.go | 47 ++++++++++++++++++++++------ 3 files changed, 79 insertions(+), 76 deletions(-) diff --git a/README.md b/README.md index d6087f9..4d21dfc 100644 --- a/README.md +++ b/README.md @@ -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. | diff --git a/handlers.go b/handlers.go index e16dc21..4ecc159 100644 --- a/handlers.go +++ b/handlers.go @@ -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) diff --git a/main.go b/main.go index 5a0f194..5a3378e 100644 --- a/main.go +++ b/main.go @@ -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) + } +}