diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 79e53a61f56971bdea32673ccd3413132510c5b5..90684582b6cd80e70122727683a48be50a59aa83 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -61,7 +61,7 @@ import-convert-assets: - master when: manual -build-dev-master: +build: image: docker:23.0 services: - docker:23.0-dind @@ -191,6 +191,6 @@ deploy_prod: - ns-ecolyo-bo-p01-syn only: - master - when: manual + diff --git a/go.mod b/go.mod index 4c42ce03fe3237953e0373c9fdecd7a073b904f3..093ba5d899a24dc496b7a7187a963e495760450e 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.18 require ( github.com/go-chi/chi/v5 v5.0.8 + github.com/google/uuid v1.3.1 golang.org/x/oauth2 v0.4.0 gorm.io/driver/mysql v1.4.7 gorm.io/driver/sqlite v1.4.4 diff --git a/go.sum b/go.sum index 8a7b8858308efcb6eaf06db379aaa2966be66911..8ec307f55c53f5046067c31a54b715a4fba176b5 100644 --- a/go.sum +++ b/go.sum @@ -8,6 +8,8 @@ github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= +github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= diff --git a/internal/common/common.go b/internal/common/common.go index c2bd4ed727a0cc09aa9b3ee07dbbf230f34665f8..7030f4e3e379847568661da255ba4f04008f8e13 100644 --- a/internal/common/common.go +++ b/internal/common/common.go @@ -173,16 +173,11 @@ func YearMonthFromRequest(r *http.Request) (year int, month int, err error) { return year, month, nil } -func IdFromRequest(r *http.Request) (id int, err error) { - idStr := chi.URLParam(r, "id") +func IdFromRequest(r *http.Request) (id string, err error) { + id = chi.URLParam(r, "id") - if idStr == "" { - return 0, errors.New("missing id") - } - - id, err = strconv.Atoi(idStr) - if err != nil { - return 0, errors.New("id is not an integer") + if id == "" { + return "", errors.New("missing id") } return id, nil diff --git a/internal/models/consent.go b/internal/models/consent.go index 88e6a1771e08b6c474226b425181b4608e74f86e..f7a528747e40aa97027c573088a5a4964752b1cf 100644 --- a/internal/models/consent.go +++ b/internal/models/consent.go @@ -9,11 +9,19 @@ import ( "forge.grandlyon.com/web-et-numerique/factory/llle_project/backoffice-server/internal/common" "forge.grandlyon.com/web-et-numerique/factory/llle_project/backoffice-server/internal/constants" + "github.com/google/uuid" "gorm.io/gorm" ) +type Base struct { + ID string `gorm:"primary_key;"` + CreatedAt time.Time + UpdatedAt time.Time + DeletedAt gorm.DeletedAt `sql:"index"` +} + type Consent struct { - gorm.Model + Base Firstname string `json:"firstname"` Lastname string `json:"lastname"` Address string `json:"address"` @@ -48,6 +56,11 @@ type UpdateConsentBody struct { ServiceID int `json:"serviceID"` } +func (b *Base) BeforeCreate(tx *gorm.DB) (err error) { + b.ID = uuid.NewString() + return +} + // GetConsentById godoc // // @Summary Get details of a specific consent @@ -66,7 +79,7 @@ func (dh *DataHandler) GetConsentById(w http.ResponseWriter, r *http.Request) { } var consent Consent - err = dh.sqlClient.First(&consent, id).Error + err = dh.sqlClient.First(&consent, "id = ?", id).Error if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { http.Error(w, "consent not found", http.StatusNotFound) @@ -149,7 +162,7 @@ func (dh *DataHandler) UpdateConsent(w http.ResponseWriter, r *http.Request) { // Find consent var consent Consent - err = dh.sqlClient.First(&consent, id).Error + err = dh.sqlClient.First(&consent, "id = ?", id).Error if err != nil { http.Error(w, "couldn't find consent", http.StatusNotFound) log.Println(err.Error()) @@ -202,7 +215,7 @@ func (dh *DataHandler) DeleteConsentById(w http.ResponseWriter, r *http.Request) } var consent = Consent{} - err = dh.sqlClient.First(&consent, id).Error + err = dh.sqlClient.First(&consent, "id = ?", id).Error if err != nil { http.Error(w, "couldn't find consent", http.StatusInternalServerError) log.Println(err.Error()) @@ -220,7 +233,7 @@ func (dh *DataHandler) DeleteConsentById(w http.ResponseWriter, r *http.Request) dh.sqlClient.Delete(&consent) - log.Printf("| deleted consent | id : %d | %v", id, r.RemoteAddr) + log.Printf("| deleted consent | id : %v | %v", id, r.RemoteAddr) } // SearchConsent godoc diff --git a/internal/rootmux/rootmux_test.go b/internal/rootmux/rootmux_test.go index 5370dbaf074e88240ccfc543911ea28e0962a083..73d1df7a6efa3e98849bfacc7a5093a091b85767 100644 --- a/internal/rootmux/rootmux_test.go +++ b/internal/rootmux/rootmux_test.go @@ -2,6 +2,7 @@ package rootmux import ( "encoding/json" + "math/rand" "net/http" "net/http/cookiejar" "net/http/httptest" @@ -14,6 +15,7 @@ import ( "forge.grandlyon.com/web-et-numerique/factory/llle_project/backoffice-server/internal/models" "forge.grandlyon.com/web-et-numerique/factory/llle_project/backoffice-server/internal/tester" "forge.grandlyon.com/web-et-numerique/factory/llle_project/backoffice-server/internal/tokens" + "github.com/google/uuid" ) const ( @@ -91,6 +93,9 @@ func TestMain(m *testing.M) { } func TestAll(t *testing.T) { + // Set uuid seed to always get the same ID during tests + uuid.SetRand(rand.New(rand.NewSource(1))) + // SGE API tests sgeTests(t) @@ -261,7 +266,7 @@ func adminTests(t *testing.T) { xsrfHeader := map[string]string{"XSRF-TOKEN": token.XSRFToken} // Try to get SGE consents (must pass) - do("GET", "/api/admin/consent?limit=50&page=0", xsrfHeader, "", http.StatusOK, `{"totalRows":2,"rows":[{"ID":2`) + do("GET", "/api/admin/consent?limit=50&page=0", xsrfHeader, "", http.StatusOK, `{"totalRows":2,"rows":[{"ID":"9566c74d-1003-4c4d-bbbb-0407d1e2c649"`) // Try to logout (must pass) do("GET", "/Logout", noH, "", http.StatusOK, "") // Try to get SGE consents again (must fail) @@ -284,17 +289,17 @@ func sgeTests(t *testing.T) { // Create correct authorization header sgeApiHeader := map[string]string{"Authorization": "Bearer " + auth.SGEApiToken} // Try to create a consent (must pass) - do("POST", "/api/sge/consent", sgeApiHeader, consentStr, http.StatusCreated, `{"ID":1`) + do("POST", "/api/sge/consent", sgeApiHeader, consentStr, http.StatusCreated, `{"ID":"52fdfc07-2182-454f-963f-5f0f9a621d72"`) // Try to create another consent (must pass) - do("POST", "/api/sge/consent", sgeApiHeader, otherConsentStr, http.StatusCreated, `{"ID":2`) + do("POST", "/api/sge/consent", sgeApiHeader, otherConsentStr, http.StatusCreated, `{"ID":"9566c74d-1003-4c4d-bbbb-0407d1e2c649"`) // Try to update a consent (must pass) - do("PUT", "/api/sge/consent/1", sgeApiHeader, `{"serviceId":123456}`, http.StatusOK, `{"ID":1`) + do("PUT", "/api/sge/consent/52fdfc07-2182-454f-963f-5f0f9a621d72", sgeApiHeader, `{"serviceId":123456}`, http.StatusOK, `{"ID":"52fdfc07-2182-454f-963f-5f0f9a621d72"`) // Try to get a consent (must pass) - do("GET", "/api/sge/consent/1", sgeApiHeader, "", http.StatusOK, `{"ID":1`) + do("GET", "/api/sge/consent/52fdfc07-2182-454f-963f-5f0f9a621d72", sgeApiHeader, "", http.StatusOK, `{"ID":"52fdfc07-2182-454f-963f-5f0f9a621d72"`) // Try to get a consent that doesn't exist (must fail not found) do("GET", "/api/sge/consent/3", sgeApiHeader, "", http.StatusNotFound, `consent not found`) // Try to delete a consent (must pass) - do("DELETE", "/api/sge/consent/1", sgeApiHeader, "", http.StatusOK, "") + do("DELETE", "/api/sge/consent/52fdfc07-2182-454f-963f-5f0f9a621d72", sgeApiHeader, "", http.StatusOK, "") } func createTester(t *testing.T) (*httptest.Server, tester.DoFn, tester.DoFn) {