diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 98605a51109e604441974182357da07fc75b7b5c..48341c4406cbc06c416e1d6da36cc3b0dbcb295f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -17,10 +17,6 @@ default: before_script: # Display Docker info - docker info - # Change directory to Go directory - - cd ./Go/ - # Shut down all services - - docker compose down # Define variables variables: @@ -84,6 +80,8 @@ Deploy: before_script: # Change directory to Go directory - cd ./Go/ + # Shut down all services + - docker compose down # Install required packages for deployment - apk add --no-cache curl bash # Download secure files diff --git a/Go/internal/handlers/endpoint/dashboard/notifications_handler.go b/Go/internal/handlers/endpoint/dashboard/notifications_handler.go index a20c98aced8accbcd98f66ccebf65ad704da3944..28687ed38b743cdc99869df9918526c5ed752e08 100644 --- a/Go/internal/handlers/endpoint/dashboard/notifications_handler.go +++ b/Go/internal/handlers/endpoint/dashboard/notifications_handler.go @@ -1,57 +1,132 @@ -// Package dashboard provides handlers for dashboard-related endpoints. +// Package dashboard provides handlers for managing dashboard-related functionalities through HTTP endpoints. package dashboard import ( + "encoding/json" + "fmt" + "globeboard/db" + _func "globeboard/internal/func" + "globeboard/internal/utils/constants" + "globeboard/internal/utils/constants/Endpoints" + "globeboard/internal/utils/structs" + "log" "net/http" ) -// NotificationsHandler handles requests to retrieve readership dashboard for a specific language. +// NotificationsHandler handles HTTP requests related to notification webhooks. func NotificationsHandler(w http.ResponseWriter, r *http.Request) { switch r.Method { - case http.MethodGet: - handleNotifGetRequest(w, r) - case http.MethodDelete: - handleNotifDeleteRequest(w, r) - case http.MethodPost: + case http.MethodPost: // Handle POST request handleNotifPostRequest(w, r) + case http.MethodGet: // Handle GET request + handleNotifGetAllRequest(w, r) default: - http.Error(w, "REST Method: "+r.Method+" not supported.", http.StatusNotImplemented) + // Log and return an error for unsupported HTTP methods + log.Printf(constants.ClientConnectUnsupported, Endpoints.Notifications, r.Method) + http.Error(w, "REST Method: "+r.Method+" not supported. Only supported methods for this endpoint is:\n"+http.MethodPost+"\n"+http.MethodGet, http.StatusNotImplemented) return } } -// handleGetRequest handles GET requests to retrieve readership dashboard for a specific language. -func handleNotifGetRequest(w http.ResponseWriter, r *http.Request) { - // Check if the link wants to get one webhook or all webhooks, and respond accordingly +// handleNotifPostRequest processes POST requests to create a new notification webhook. +func handleNotifPostRequest(w http.ResponseWriter, r *http.Request) { + query := r.URL.Query() // Extract the query parameters. + token := query.Get("token") // Retrieve token from the URL query parameters. + if token == "" { // Check if a token is provided. + log.Printf(constants.ClientConnectNoToken, r.Method, Endpoints.Notifications) + http.Error(w, ProvideAPI, http.StatusUnauthorized) + return + } + UUID := db.GetAPIKeyUUID(token) // Retrieve UUID associated with the API token. + if UUID == "" { // Check if UUID is valid. + log.Printf(constants.ClientConnectUnauthorized, r.Method, Endpoints.Notifications) + err := fmt.Sprintf(APINotAccepted) + http.Error(w, err, http.StatusNotAcceptable) + return + } - // Make system take JSON + if r.Body == nil { // Check if request body is empty. + log.Printf(constants.ClientConnectEmptyBody, r.Method, Endpoints.Notifications) + err := fmt.Sprintf("Please send a request body") + http.Error(w, err, http.StatusBadRequest) + return + } - // Then send ID back -} + var webhook *structs.WebhookInternal + if err := json.NewDecoder(r.Body).Decode(&webhook); err != nil { // Decode the JSON request body into webhook struct. + err := fmt.Sprintf("Error decoding request body: %v", err) + http.Error(w, err, http.StatusBadRequest) + return + } -func handleNotifDeleteRequest(w http.ResponseWriter, r *http.Request) { - // Given the id from the url, delete the request + UDID := _func.GenerateUID(constants.DocIdLength) // Generate a unique document ID. + ID := _func.GenerateUID(constants.IdLength) // Generate a unique ID for the webhook. - // Fetch the id from URL + webhook.ID = ID + webhook.UUID = UUID - // Check if webhook with that id exists + err := db.AddWebhook(UDID, webhook) // Add the webhook to the database. + if err != nil { + log.Println("Error saving data to database" + err.Error()) + http.Error(w, "Error storing data in database", http.StatusInternalServerError) + return + } - // exists: delete - // (optional) Ask for deletion + hook, err := db.GetSpecificWebhook(ID, UUID) // Retrieve the newly added webhook to confirm its addition. + if err != nil { + log.Print("Error getting document from database: ", err) + http.Error(w, "Error confirming data added to database", http.StatusInternalServerError) + return + } - // Perform deletion - // Reorder? -} + response := map[string]interface{}{ + "id": hook.ID, // Prepare response data with the new webhook ID. + } -func handleNotifPostRequest(w http.ResponseWriter, r *http.Request) { + w.Header().Set(ContentType, ApplicationJSON) // Set the content type of the response. - // Get url + w.WriteHeader(http.StatusCreated) // Set HTTP status to "Created". - // Check if url has an additional parameter + err = json.NewEncoder(w).Encode(response) // Encode the response as JSON and send it. + if err != nil { + log.Print(err) + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } +} - // Has parameter - // +// handleNotifGetAllRequest processes GET requests to retrieve all notification webhooks for a user. +func handleNotifGetAllRequest(w http.ResponseWriter, r *http.Request) { + query := r.URL.Query() // Extract the query parameters. + token := query.Get("token") // Retrieve token from the URL query parameters. + if token == "" { // Check if a token is provided. + log.Printf(constants.ClientConnectNoToken, r.Method, Endpoints.Notifications) + http.Error(w, ProvideAPI, http.StatusUnauthorized) + return + } + UUID := db.GetAPIKeyUUID(token) // Retrieve UUID associated with the API token. + if UUID == "" { // Check if UUID is valid. + log.Printf(constants.ClientConnectUnauthorized, r.Method, Endpoints.Notifications) + err := fmt.Sprintf(APINotAccepted) + http.Error(w, err, http.StatusNotAcceptable) + return + } + regs, err := db.GetWebhooksUser(UUID) // Retrieve all webhooks associated with the user (UUID). + if err != nil { + log.Printf("Error retrieving webhooks from database: %v", err) + errmsg := fmt.Sprint("Error retrieving webhooks from database: ", err) + http.Error(w, errmsg, http.StatusInternalServerError) + return + } + + w.Header().Set(ContentType, ApplicationJSON) // Set the content type of the response. - // Has no parameter - // Show all webhooks + w.WriteHeader(http.StatusOK) // Set HTTP status to "OK". + + err = json.NewEncoder(w).Encode(regs) // Encode the webhooks as JSON and send it. + if err != nil { + log.Print(err) + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } }