diff --git a/internal/models/election.go b/internal/models/election.go new file mode 100644 index 0000000000000000000000000000000000000000..00f4a11fb71c2ac865ef03e2c7b0d9f5d1f5a561 --- /dev/null +++ b/internal/models/election.go @@ -0,0 +1,113 @@ +package models + +import ( + "encoding/json" + "net/http" + "strconv" + "strings" + + "forge.grandlyon.com/apoyen/elections/internal/auth" +) + +func (d *DataHandler) HandleElection(w http.ResponseWriter, r *http.Request) { + id, _ := strconv.Atoi(strings.TrimPrefix(r.URL.Path, "/api/Election/")) + switch method := r.Method; method { + case "GET": + switch auth.GetLoggedUserTechnical(w, r).Role { + case "ADMIN": + d.getElectionAdmin(w, r, id) + case "CAPTURER", "VISUALIZER": + http.Error(w, ErrorNotAuthorizeMethodOnRessource, http.StatusMethodNotAllowed) + default: + http.Error(w, ErrorRoleOfLoggedUser, http.StatusInternalServerError) + } + case "POST": + switch auth.GetLoggedUserTechnical(w, r).Role { + case "ADMIN": + d.postElectionAdmin(w, r) + case "CAPTURER", "VISUALIZER": + http.Error(w, ErrorNotAuthorizeMethodOnRessource, http.StatusMethodNotAllowed) + default: + http.Error(w, ErrorRoleOfLoggedUser, http.StatusInternalServerError) + } + + case "PUT": + switch auth.GetLoggedUserTechnical(w, r).Role { + case "ADMIN": + d.putElectionAdmin(w, r, id) + case "CAPTURER", "VISUALIZER": + http.Error(w, ErrorNotAuthorizeMethodOnRessource, http.StatusMethodNotAllowed) + default: + http.Error(w, ErrorRoleOfLoggedUser, http.StatusInternalServerError) + } + case "DELETE": + switch auth.GetLoggedUserTechnical(w, r).Role { + case "ADMIN": + d.deleteElectionAdmin(w, r, id) + case "CAPTURER", "VISUALIZER": + http.Error(w, ErrorNotAuthorizeMethodOnRessource, http.StatusMethodNotAllowed) + default: + http.Error(w, ErrorRoleOfLoggedUser, http.StatusInternalServerError) + } + default: + http.Error(w, "method not allowed", 400) + } +} + +func (d *DataHandler) getElectionAdmin(w http.ResponseWriter, r *http.Request, id int) { + if id != 0 { + var o Election + if err := d.db.Preload("Areas").First(&o, id).Error; err != nil { + http.Error(w, ErrorIDIsMissing, http.StatusNotFound) + return + } + json.NewEncoder(w).Encode(o) + } else { + var o []Election + d.db.Preload("Areas").Find(&o) + json.NewEncoder(w).Encode(o) + } +} + +func (d *DataHandler) postElectionAdmin(w http.ResponseWriter, r *http.Request) { + var o Election + err := json.NewDecoder(r.Body).Decode(&o) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + } + d.db.Create(&o) + d.db.Last(&o) + json.NewEncoder(w).Encode(o) + +} + +func (d *DataHandler) putElectionAdmin(w http.ResponseWriter, r *http.Request, id int) { + var o Election + if err := d.db.Preload("Areas").First(&o, id).Error; err != nil { + http.Error(w, ErrorIDIsMissing, http.StatusNotFound) + return + } + var election Election + err := json.NewDecoder(r.Body).Decode(&election) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + } + o.Name = election.Name + o.BallotType = election.BallotType + d.db.Save(&o) + json.NewEncoder(w).Encode(o) + +} + +func (d *DataHandler) deleteElectionAdmin(w http.ResponseWriter, r *http.Request, id int) { + if id != 0 { + var o Election + if err := d.db.First(&o, id).Error; err != nil { + http.Error(w, ErrorIDIsMissing, http.StatusNotFound) + return + } + d.db.Delete(&o) + } else { + http.Error(w, ErrorIDIsMissing, http.StatusNotFound) + } +} diff --git a/internal/models/models.go b/internal/models/models.go index 858791b68c303133d158354ab7e38f6a1ab9af38..e2371675fbda232ee29b0e8fb5bb806ae5cf32c5 100644 --- a/internal/models/models.go +++ b/internal/models/models.go @@ -216,6 +216,8 @@ func (d *DataHandler) ProcessAPI(w http.ResponseWriter, r *http.Request) { switch api { case "Capturer": d.HandleCapturer(w, r) + case "Election": + d.HandleElection(w, r) } } diff --git a/internal/rootmux/admin_test.go b/internal/rootmux/admin_test.go index ba9dc3b2045ff080574b25098862fc99febdc263..12082873dc589318264268f02a9f0f99c677ea51 100644 --- a/internal/rootmux/admin_test.go +++ b/internal/rootmux/admin_test.go @@ -33,6 +33,17 @@ func AdminTests(t *testing.T) { // Delete a capturer do("DELETE", "/api/Capturer/3", xsrfHeader, ``, 200, ``) + // Create an Election + do("POST", "/api/Election", xsrfHeader, `{"Name":"Grand Lyon 2020", "BallotType":"metropolitan-direct"}`, 200, `{"ID":1,"Name":"Grand Lyon 2020","BallotType":"metropolitan-direct","Areas":null,"Rounds":null}`) + // Get the election + do("GET", "/api/Election/1", xsrfHeader, ``, 200, `{"ID":1,"Name":"Grand Lyon 2020","BallotType":"metropolitan-direct","Areas":[],"Rounds":null}`) + // Get all the elections + do("GET", "/api/Election/", xsrfHeader, ``, 200, `[{"ID":1,"Name":"Grand Lyon 2020","BallotType":"metropolitan-direct","Areas":[],"Rounds":null}]`) + // Update a election + do("PUT", "/api/Election/1", xsrfHeader, `{"ID":1,"Name":"Grand-Lyon 2020", "BallotType":"metropolitan-direct"}`, 200, `{"ID":1,"Name":"Grand-Lyon 2020","BallotType":"metropolitan-direct","Areas":[],"Rounds":null}`) + // Delete a election + do("DELETE", "/api/Election/1", xsrfHeader, ``, 200, ``) + } // Do a in memory login with an known admin do("POST", "/Login", noH, `{"login": "admin","password": "password"}`, 200, "") diff --git a/internal/rootmux/capturer_test.go b/internal/rootmux/capturer_test.go index 741c7a8a269c7540b783024d381255a7d4d29b4a..0f91790f0e855c02a7d11aee17d07689b522d5a3 100644 --- a/internal/rootmux/capturer_test.go +++ b/internal/rootmux/capturer_test.go @@ -35,6 +35,17 @@ func CapturerTests(t *testing.T) { // Delete a capturer should fail with 405 do("DELETE", "/api/Capturer/1", xsrfHeader, ``, 405, `You're not authorize to execute this method on this ressource.`) + // Create an election should fail with 405 + do("POST", "/api/Election", xsrfHeader, `{"Name":"Grand Lyon 2020", "BallotType":"metropolitan-direct"}`, 405, `You're not authorize to execute this method on this ressource.`) + // Get an Election should fail with 405 + do("GET", "/api/Election/1", xsrfHeader, "", 405, `You're not authorize to execute this method on this ressource.`) + // Get all the elections should fail with 405 + do("GET", "/api/Election/", xsrfHeader, "", 405, `You're not authorize to execute this method on this ressource.`) + // Update an election should fail with 405 + do("PUT", "/api/Election/1", xsrfHeader, `{"Name":"Grand Lyon 2020", "BallotType":"metropolitan-direct"}`, 405, `You're not authorize to execute this method on this ressource.`) + // Delete an election should fail with 405 + do("DELETE", "/api/Election/1", xsrfHeader, ``, 405, `You're not authorize to execute this method on this ressource.`) + } // Do a in memory login with an known admin do("POST", "/Login", noH, `{"login": "capturer","password": "password"}`, 200, "") diff --git a/internal/rootmux/visualizer_test.go b/internal/rootmux/visualizer_test.go index 8a8b94909a0f9481bcc048f041e7ab12787cb46f..08841a72b871f99fad2187b6d258d57978c54b0a 100644 --- a/internal/rootmux/visualizer_test.go +++ b/internal/rootmux/visualizer_test.go @@ -33,6 +33,17 @@ func VisualizerTests(t *testing.T) { // Delete a capturer should fail with 405 do("DELETE", "/api/Capturer/1", xsrfHeader, ``, 405, `You're not authorize to execute this method on this ressource.`) + // Create an election should fail with 405 + do("POST", "/api/Election", xsrfHeader, `{"Name":"Grand Lyon 2020", "BallotType":"metropolitan-direct"}`, 405, `You're not authorize to execute this method on this ressource.`) + // Get an Election should fail with 405 + do("GET", "/api/Election/1", xsrfHeader, "", 405, `You're not authorize to execute this method on this ressource.`) + // Get all the elections should fail with 405 + do("GET", "/api/Election/", xsrfHeader, "", 405, `You're not authorize to execute this method on this ressource.`) + // Update an election should fail with 405 + do("PUT", "/api/Election/1", xsrfHeader, `{"Name":"Grand Lyon 2020", "BallotType":"metropolitan-direct"}`, 405, `You're not authorize to execute this method on this ressource.`) + // Delete an election should fail with 405 + do("DELETE", "/api/Election/1", xsrfHeader, ``, 405, `You're not authorize to execute this method on this ressource.`) + } // Do a in memory login with an known admin do("POST", "/Login", noH, `{"login": "visualizer","password": "password"}`, 200, "")