diff --git a/docker-compose.yml b/docker-compose.yml index 02ddcce728aa6ef6aaa7f365538a90f2993b4443..d14130116f3cc2d8b4be45fc7533b4a7fcc9dd4d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -35,6 +35,7 @@ services: - ./configs:/app/configs - ./letsencrypt_cache:/app/letsencrypt_cache - ./data:/app/data + - ./../${IMAGE_FOLDER}:/app/${IMAGE_FOLDER} ports: - ${HTTPS_PORT}:${HTTPS_PORT} - 8090:8090 @@ -43,6 +44,7 @@ services: - HTTPS_PORT=${HTTPS_PORT} - ADMIN_ROLE=${ADMIN_ROLE} - REDIRECT_URL=${REDIRECT_URL} + - IMAGE_FOLDER=${IMAGE_FOLDER} - CLIENT_ID=${CLIENT_ID} - CLIENT_SECRET=${CLIENT_SECRET} - AUTH_URL=${AUTH_URL} diff --git a/internal/file/file.go b/internal/file/file.go new file mode 100644 index 0000000000000000000000000000000000000000..dba702c99bb34f643fa9a30221f599c7a8e200eb --- /dev/null +++ b/internal/file/file.go @@ -0,0 +1,38 @@ +package file + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "log" + "net/http" + + "forge.grandlyon.com/web-et-numerique/llle_project/backoffice-server/internal/common" +) + +var imageFolder = common.StringValueFromEnv("IMAGE_FOLDER", "") + +func GetEcogestureImages(w http.ResponseWriter, r *http.Request) { + filenames, err := fileNamesFromFolder(imageFolder) + jsondata, err := json.Marshal(filenames) + if err != nil { + fmt.Printf("Error: %s", err.Error()) + return + } + + w.Header().Set("Content-Type", "application/json") + w.Write(jsondata) + log.Printf("| get image names | %v", r.RemoteAddr) +} + +func fileNamesFromFolder(folder string) (filenames []string, err error) { + files, err := ioutil.ReadDir(folder) + if err != nil { + return nil, err + } + + for _, file := range files { + filenames = append(filenames, file.Name()) + } + return filenames, nil +} diff --git a/internal/file/file_test.go b/internal/file/file_test.go new file mode 100644 index 0000000000000000000000000000000000000000..d8dcc99b3b5b767933c9633adea7139ece1fab46 --- /dev/null +++ b/internal/file/file_test.go @@ -0,0 +1,38 @@ +package file + +import ( + "encoding/json" + "log" + "os" + "testing" +) + +func TestFilenamesFromFolder(t *testing.T) { + + // Create temporary file + err := os.MkdirAll("test", 0755) + if err != nil { + log.Fatal(err) + } + // Create some files + os.Create("test/file1") + os.Create("test/file2") + os.Create("test/file3") + expected := `["file1","file2","file3"]` + + filenames, err := fileNamesFromFolder("test") + if err != nil { + t.Errorf(`error: %s`, err) + return + } + jsondata, err := json.Marshal(filenames) + if err != nil { + t.Errorf(`error: %s`, err) + return + } + if string(jsondata) != expected { + t.Errorf(`unexpected answer: got %s want %s`, string(jsondata), expected) + return + } + os.RemoveAll("test") +} diff --git a/internal/models/monthlyInfo.go b/internal/models/monthlyInfo.go index d55b7f2c9a025f92c043f1d52c41c0184e6430d1..5425f8b5e41b57a6c004aa76205d116f0fefa532 100644 --- a/internal/models/monthlyInfo.go +++ b/internal/models/monthlyInfo.go @@ -12,6 +12,7 @@ type MonthlyInfo struct { Year int `json:"year"` Month int `json:"month"` Info string `json:"info"` + Image string `json:"image"` } // GetAllMonthlyInfo godoc @@ -44,6 +45,7 @@ func (dh *DataHandler) GetSingleMonthlyInfo(w http.ResponseWriter, r *http.Reque year, month, err := common.YearMonthFromRequest(r) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) + return } w.Header().Set("Content-Type", "application/json") @@ -89,7 +91,12 @@ func (dh *DataHandler) SaveMonthlyInfo(w http.ResponseWriter, r *http.Request) { if err != nil { // Create a monthlyInfo - err = dh.db.Create(&MonthlyInfo{Year: monthlyInfo.Year, Month: monthlyInfo.Month, Info: monthlyInfo.Info}).Error + err = dh.db.Create(&MonthlyInfo{ + Year: monthlyInfo.Year, + Month: monthlyInfo.Month, + Info: monthlyInfo.Info, + Image: monthlyInfo.Image, + }).Error if err != nil { w.WriteHeader(http.StatusInternalServerError) return @@ -108,6 +115,13 @@ func (dh *DataHandler) SaveMonthlyInfo(w http.ResponseWriter, r *http.Request) { return } + // Update info + err = dh.db.Model(&MonthlyInfo{}).Where("year = ? AND month = ?", monthlyInfo.Year, monthlyInfo.Month).Update("image", monthlyInfo.Image).Error + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + return + } + json.NewEncoder(w).Encode(monthlyInfo) log.Printf("| updated monthlyInfo | year : %d month : %d | %v", monthlyInfo.Year, monthlyInfo.Month, r.RemoteAddr) } @@ -127,6 +141,7 @@ func (dh *DataHandler) DeleteMonthlyInfo(w http.ResponseWriter, r *http.Request) year, month, err := common.YearMonthFromRequest(r) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) + return } err = dh.db.Where("year = ? AND month = ?", year, month).Delete(&MonthlyInfo{}).Error diff --git a/internal/models/monthlyNews.go b/internal/models/monthlyNews.go index aba3db0b7cee190f5db2eeb0d0093264ec11c3dd..5a7ce8e9c1ca8c2960fc5c180817846e91e2eede 100644 --- a/internal/models/monthlyNews.go +++ b/internal/models/monthlyNews.go @@ -45,6 +45,7 @@ func (dh *DataHandler) GetSingleMonthlyNews(w http.ResponseWriter, r *http.Reque year, month, err := common.YearMonthFromRequest(r) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) + return } w.Header().Set("Content-Type", "application/json") @@ -140,6 +141,7 @@ func (dh *DataHandler) DeleteMonthlyNews(w http.ResponseWriter, r *http.Request) year, month, err := common.YearMonthFromRequest(r) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) + return } err = dh.db.Where("year = ? AND month = ?", year, month).Delete(&MonthlyNews{}).Error diff --git a/internal/models/monthlyReport.go b/internal/models/monthlyReport.go index 03b211015e42576d86e9a59fa921393a8574d389..eb8816b95b15aae5e2929ee2cd8cda6ff0a0af24 100644 --- a/internal/models/monthlyReport.go +++ b/internal/models/monthlyReport.go @@ -12,6 +12,7 @@ type MonthlyReport struct { Year int `json:"year"` Month int `json:"month"` Info string `json:"info"` + Image string `json:"image"` NewsTitle string `json:"newsTitle"` NewsContent string `json:"newsContent"` Question string `json:"question"` @@ -84,6 +85,7 @@ func (dh *DataHandler) getMonthlyReport(year int, month int) (monthlyReport Mont Year: year, Month: month, Info: monthlyInfo.Info, + Image: monthlyInfo.Image, NewsTitle: monthlyNews.Title, NewsContent: monthlyNews.Content, Question: poll.Question, diff --git a/internal/models/poll.go b/internal/models/poll.go index aea9836591873b98c18afc4ee927d6bae15c5c89..76acbc8dac5585019cc47f8c6f28945fcb5a235e 100644 --- a/internal/models/poll.go +++ b/internal/models/poll.go @@ -49,6 +49,7 @@ func (dh *DataHandler) GetSinglePoll(w http.ResponseWriter, r *http.Request) { year, month, err := common.YearMonthFromRequest(r) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) + return } w.Header().Set("Content-Type", "application/json") @@ -137,6 +138,7 @@ func (dh *DataHandler) DeletePoll(w http.ResponseWriter, r *http.Request) { year, month, err := common.YearMonthFromRequest(r) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) + return } err = dh.db.Where("year = ? AND month = ?", year, month).Delete(&Poll{}).Error diff --git a/internal/rootmux/rootmux.go b/internal/rootmux/rootmux.go index aca639a98858d5a4edfcd9c5ed6d5d3fe75a14ce..84307853fc0f8bb6e6803b2f4674d3625708fabd 100644 --- a/internal/rootmux/rootmux.go +++ b/internal/rootmux/rootmux.go @@ -5,6 +5,7 @@ import ( _ "forge.grandlyon.com/web-et-numerique/llle_project/backoffice-server/docs" "forge.grandlyon.com/web-et-numerique/llle_project/backoffice-server/internal/auth" + "forge.grandlyon.com/web-et-numerique/llle_project/backoffice-server/internal/file" "forge.grandlyon.com/web-et-numerique/llle_project/backoffice-server/internal/models" "github.com/gorilla/mux" httpSwagger "github.com/swaggo/http-swagger" @@ -56,6 +57,8 @@ func CreateRootMux() RootMux { apiAdmin.HandleFunc("/poll", dh.SavePoll).Methods(http.MethodPut) apiAdmin.HandleFunc("/poll/{year}/{month}", dh.DeletePoll).Methods(http.MethodDelete) + apiAdmin.HandleFunc("/imageNames", file.GetEcogestureImages).Methods(http.MethodGet) + // Swagger r.PathPrefix("/swagger").Handler(httpSwagger.WrapHandler) diff --git a/internal/rootmux/rootmux_test.go b/internal/rootmux/rootmux_test.go index 5e6a66f863ddbbf71526d73ca70cd547137206c0..9fa492dc35d827089db7d6e0023fa7ff99e3260b 100644 --- a/internal/rootmux/rootmux_test.go +++ b/internal/rootmux/rootmux_test.go @@ -18,7 +18,7 @@ import ( var ( oAuth2Server *httptest.Server - monthlyInfo = models.MonthlyInfo{Year: 2021, Month: 0, Info: "Informations du mois"} + monthlyInfo = models.MonthlyInfo{Year: 2021, Month: 0, Info: "Informations du mois", Image: "imagebase64"} monthlyInfoStr string monthlyNews = models.MonthlyNews{Year: 2021, Month: 0, Title: "", Content: "Nouvelles fonctionnalités"} monthlyNewsStr string @@ -154,20 +154,20 @@ func adminTests(t *testing.T) { // Try to get the monthlyInfo created (must pass) do("GET", "/api/admin/monthlyInfo/2021/0", xsrfHeader, "", http.StatusOK, monthlyInfoStr) // Try to get the monthlyReport (must pass) - do("GET", "/api/common/monthlyReport/2021/0", noH, "", http.StatusOK, `{"year":2021,"month":0,"info":"Informations du mois","newsTitle":"Les nouveautés du service","newsContent":"Nouvelles fonctionnalités","question":"pollQuestion","link":"pollLink"`) + do("GET", "/api/common/monthlyReport/2021/0", noH, "", http.StatusOK, `{"year":2021,"month":0,"info":"Informations du mois","image":"imagebase64","newsTitle":"Les nouveautés du service","newsContent":"Nouvelles fonctionnalités","question":"pollQuestion","link":"pollLink"`) // Try to delete the monthlyNews created (must pass) do("DELETE", "/api/admin/monthlyNews/2021/0", xsrfHeader, "", http.StatusOK, "successful delete") // Try to get a monthlyNews after it is deleted (must fail because not found) do("GET", "/api/admin/monthlyNews/2021/0", xsrfHeader, "", http.StatusNotFound, "") // Try to get the monthlyReport (must pass) - do("GET", "/api/common/monthlyReport/2021/0", noH, "", http.StatusOK, `{"year":2021,"month":0,"info":"Informations du mois","newsTitle":"","newsContent":"","question":"pollQuestion","link":"pollLink"`) + do("GET", "/api/common/monthlyReport/2021/0", noH, "", http.StatusOK, `{"year":2021,"month":0,"info":"Informations du mois","image":"imagebase64","newsTitle":"","newsContent":"","question":"pollQuestion","link":"pollLink"`) // Try to delete the poll created (must pass) do("DELETE", "/api/admin/poll/2021/0", xsrfHeader, "", http.StatusOK, "successful delete") // Try to get a poll after it is deleted (must fail because not found) do("GET", "/api/admin/poll/2021/0", xsrfHeader, "", http.StatusNotFound, "") // Try to get the monthlyReport (must pass) - do("GET", "/api/common/monthlyReport/2021/0", noH, "", http.StatusOK, `{"year":2021,"month":0,"info":"Informations du mois","newsTitle":"","newsContent":"","question":"","link":""`) + do("GET", "/api/common/monthlyReport/2021/0", noH, "", http.StatusOK, `{"year":2021,"month":0,"info":"Informations du mois","image":"imagebase64","newsTitle":"","newsContent":"","question":"","link":""`) } // Try to login (must pass) do("GET", "/OAuth2Login", noH, "", http.StatusOK, "") diff --git a/template.env b/template.env index efe3ecf1bffc83f0012a9d8e269e4a69cc660339..46c59570a6efe18afdc9997e871923124479cfe0 100644 --- a/template.env +++ b/template.env @@ -4,6 +4,7 @@ ADMIN_ROLE= DEBUG_MODE= MOCK_OAUTH2= HTTPS_PORT= +IMAGE_FOLDER= # Needed to user OAuth2 authentication : REDIRECT_URL=