diff --git a/Dockerfile b/Dockerfile index 6f77d91..7497889 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.20.6 as build +FROM golang:1.21.0 as build LABEL author="Victor Lacasse-Beaudoin " @@ -24,9 +24,7 @@ RUN CGO_ENABLED=0 go build -a -installsuffix cgo -o agecem-org . # Alpine -FROM alpine:3.17.2 - -RUN apk update && apk upgrade --no-cache +FROM alpine:3.18.3 WORKDIR /app diff --git a/cmd/server.go b/cmd/server.go index 5173374..84a2b25 100644 --- a/cmd/server.go +++ b/cmd/server.go @@ -96,7 +96,12 @@ func init() { viper.BindPFlag("server.documents.use_ssl", serverCmd.Flags().Lookup("server-documents-use-ssl")) // server.documents.buckets - --server-documents-buckets - serverCmd.Flags().StringSlice("server-documents-buckets", []string{"proces-verbaux", "politiques-et-reglements"}, "Buckets that are allowed to be accessed by the API (config: server.documents.buckets)") + serverCmd.Flags().StringToString("server-documents-buckets", map[string]string{ + "proces-verbaux": "Procès-verbaux", + "politiques": "Politiques", + "reglements": "Règlements", + "formulaires": "Formulaires", + }, "Buckets that are allowed to be accessed by the API (config: server.documents.buckets)") viper.BindPFlag("server.documents.buckets", serverCmd.Flags().Lookup("server-documents-buckets")) // server.api.auth - --server-api-auth @@ -293,7 +298,7 @@ func handleDocumentation(c echo.Context) error { return c.Render(http.StatusInternalServerError, "documentation-html", nil) } - var buckets []string + var buckets map[string]string err = json.Unmarshal(result, &buckets) if err != nil { @@ -301,13 +306,14 @@ func handleDocumentation(c echo.Context) error { } type Bucket struct { - Name string - Documents []string + Name string + DisplayName string + Documents []string } var data []Bucket - for _, bucket := range buckets { + for bucket, displayName := range buckets { content, err := client.Call(http.MethodGet, fmt.Sprintf("/v1/bucket/%s", bucket)) if err != nil { return c.Render(http.StatusInternalServerError, "documentation-html", nil) @@ -339,8 +345,9 @@ func handleDocumentation(c echo.Context) error { */ data = append(data, Bucket{ - Name: bucket, - Documents: documents, + Name: bucket, + DisplayName: displayName, + Documents: documents, }) } @@ -381,10 +388,56 @@ func handleAdmin(c echo.Context) error { } func handleAdminDocumentsUpload(c echo.Context) error { - return c.Render(http.StatusOK, "admin-upload-html", nil) + client, err := api.NewApiClientFromViper() + if err != nil { + return c.Render(http.StatusInternalServerError, "documentation-html", nil) + } + + result, err := client.Call(http.MethodGet, "/v1/bucket") + if err != nil { + return c.Render(http.StatusInternalServerError, "documentation-html", nil) + } + + var buckets map[string]string + + err = json.Unmarshal(result, &buckets) + if err != nil { + return c.Render(http.StatusInternalServerError, "documentation-html", nil) + } + + type Bucket struct { + Name string + DisplayName string + Documents []string + } + + var data struct { + Buckets []Bucket + Message string + } + + for bucketName, displayName := range buckets { + data.Buckets = append(data.Buckets, Bucket{ + Name: bucketName, + DisplayName: displayName, + }) + } + + return c.Render(http.StatusOK, "admin-upload-html", data) } func handleAdminDocumentsUploadPOST(c echo.Context) error { + type Bucket struct { + Name string + DisplayName string + Documents []string + } + + var data struct { + Buckets []Bucket + Message string + } + client, err := api.New(cfg.Server.Api.Protocol, cfg.Server.Api.Host, cfg.Server.Port, api.APIOptions{ KeyAuth: cfg.Server.Api.Auth, Key: cfg.Server.Api.Key, @@ -393,29 +446,52 @@ func handleAdminDocumentsUploadPOST(c echo.Context) error { Password: cfg.Server.Admin.Password, }) if err != nil { - return c.Render(http.StatusInternalServerError, "admin-upload-html", struct{ Message string }{Message: fmt.Sprintf("handleAdminDocumentsUploadPOST#api.New: %s", err)}) + data.Message = fmt.Sprintf("handleAdminDocumentsUploadPOST#api.New: %s", err) + return c.Render(http.StatusInternalServerError, "admin-upload-html", data) + } + + result, err := client.Call(http.MethodGet, "/v1/bucket") + if err != nil { + data.Message = "Error during GET /v1/bucket" + return c.Render(http.StatusInternalServerError, "documentation-html", data) + } + + var buckets map[string]string + + err = json.Unmarshal(result, &buckets) + if err != nil { + return c.Render(http.StatusInternalServerError, "documentation-html", nil) + } + + for bucketName, displayName := range buckets { + data.Buckets = append(data.Buckets, Bucket{ + Name: bucketName, + DisplayName: displayName, + }) } bucket := c.FormValue("bucket") document, err := c.FormFile("document") if err != nil { - return c.Render(http.StatusBadRequest, "admin-upload-html", struct{ Message string }{Message: fmt.Sprintf("handleAdminDocumentsUploadPOST#c.FormFile: %s", err)}) + data.Message = fmt.Sprintf("handleAdminDocumentsUploadPOST#c.FormFile: %s", err) + return c.Render(http.StatusBadRequest, "admin-upload-html", data) } response, err := client.UploadDocument(bucket, document) if err != nil { - return c.Render(http.StatusInternalServerError, "admin-upload-html", struct{ Message string }{Message: fmt.Sprintf("handleAdminDocumentsUploadPOST#client.UploadDocument: %s", err)}) + data.Message = fmt.Sprintf("handleAdminDocumentsUploadPOST#client.UploadDocument: %s", err) + return c.Render(http.StatusInternalServerError, "admin-upload-html", data) } // Format response - var message, info, status string + var info, status string info = fmt.Sprintf("[%.0f] /public/documentation/%s/%s", response.Info.Size, response.Info.Bucket, response.Info.Object) status = response.Message - message = fmt.Sprintf("%s - %s", status, info) + data.Message = fmt.Sprintf("%s - %s", status, info) - return c.Render(http.StatusOK, "admin-upload-html", struct{ Message string }{Message: message}) + return c.Render(http.StatusOK, "admin-upload-html", data) } diff --git a/config/config.go b/config/config.go index d2d637a..26f1a95 100644 --- a/config/config.go +++ b/config/config.go @@ -28,13 +28,13 @@ type Config struct { Protocol string `mapstructure:"protocol"` } `mapstructure:"api"` Documents struct { - AccessKeyId string `mapstructure:"access_key_id"` - Buckets []string `mapstructure:"buckets"` - Endpoint string `mapstructure:"endpoint"` - SecretAccessKey string `mapstructure:"secret_access_key"` - UseSSL bool `mapstructure:"use_ssl"` - KeyId string `mapstructure:"keyid"` - KeyValue string `mapstructure:"keyvalue"` + AccessKeyId string `mapstructure:"access_key_id"` + Buckets map[string]string `mapstructure:"buckets"` + Endpoint string `mapstructure:"endpoint"` + SecretAccessKey string `mapstructure:"secret_access_key"` + UseSSL bool `mapstructure:"use_ssl"` + KeyId string `mapstructure:"keyid"` + KeyValue string `mapstructure:"keyvalue"` } `mapstructure:"documents"` Port int `mapstructure:"port"` } `mapstructure:"server"` diff --git a/examples/config/agecem-org.yaml b/examples/config/agecem-org.yaml index 55a2535..5d77cf5 100644 --- a/examples/config/agecem-org.yaml +++ b/examples/config/agecem-org.yaml @@ -35,8 +35,10 @@ server: # # Also used to specify which buckets are to be created on receiving a POST request on /v1/seed buckets: - - 'proces-verbaux' - - 'politiques-et-reglements' + 'proces-verbaux': 'Procès-verbaux' + 'politiques': 'Politiques' + 'reglements': 'Règlements' + 'formulaires': 'Formulaires' api: # Enable or disable key auth on /v1 routes diff --git a/media/media.go b/media/media.go index 8f22e8f..b5cb765 100644 --- a/media/media.go +++ b/media/media.go @@ -58,7 +58,7 @@ func (m *MediaClient) Seed() ([]string, error) { var new_buckets []string - for _, bucket := range cfg.Server.Documents.Buckets { + for bucket := range cfg.Server.Documents.Buckets { exists, err := m.MinioClient.BucketExists(context.Background(), bucket) if err != nil { return new_buckets, err diff --git a/serverhandlers/serverhandlers.go b/serverhandlers/serverhandlers.go index eb688b5..6aca6d1 100644 --- a/serverhandlers/serverhandlers.go +++ b/serverhandlers/serverhandlers.go @@ -72,16 +72,16 @@ func HandleV1BucketList(c echo.Context) error { }) } - var buckets []string + var buckets = make(map[string]string) - for _, bucket_name := range cfg.Server.Documents.Buckets { + for bucket_name, bucket_display_name := range cfg.Server.Documents.Buckets { exists, err := mediaClient.MinioClient.BucketExists(context.Background(), bucket_name) if err != nil { return c.JSON(http.StatusInternalServerError, "Error during minio#BucketExists") } if exists { - buckets = append(buckets, bucket_name) + buckets[bucket_name] = bucket_display_name } } @@ -99,7 +99,7 @@ func HandleV1BucketRead(c echo.Context) error { bucket := c.Param("bucket") allowed := false - for _, bucket_allowed := range cfg.Server.Documents.Buckets { + for bucket_allowed := range cfg.Server.Documents.Buckets { if bucket == bucket_allowed { allowed = true } @@ -171,7 +171,7 @@ func HandleV1DocumentCreate(c echo.Context) error { } allowed := false - for _, bucket_allowed := range cfg.Server.Documents.Buckets { + for bucket_allowed := range cfg.Server.Documents.Buckets { if bucket == bucket_allowed { allowed = true } @@ -240,7 +240,7 @@ func HandleV1DocumentRead(c echo.Context) error { document := c.Param("document") allowed := false - for _, bucket_allowed := range cfg.Server.Documents.Buckets { + for bucket_allowed := range cfg.Server.Documents.Buckets { if bucket == bucket_allowed { allowed = true } @@ -317,7 +317,7 @@ func HandleV1DocumentDelete(c echo.Context) error { document := c.Param("document") allowed := false - for _, bucket_allowed := range cfg.Server.Documents.Buckets { + for bucket_allowed := range cfg.Server.Documents.Buckets { if bucket == bucket_allowed { allowed = true } diff --git a/templates/html/admin-upload.gohtml b/templates/html/admin-upload.gohtml index 1729ba0..c7afd53 100644 --- a/templates/html/admin-upload.gohtml +++ b/templates/html/admin-upload.gohtml @@ -12,8 +12,9 @@

Document: diff --git a/templates/html/documentation.gohtml b/templates/html/documentation.gohtml index 2f432f3..02849a2 100644 --- a/templates/html/documentation.gohtml +++ b/templates/html/documentation.gohtml @@ -13,13 +13,15 @@

{{ range . }} {{ $bucket_name := .Name }} + {{ $bucket_display_name := .DisplayName }}

- {{ $bucket_name }} -
    - {{ range .Documents }} -
  • {{ . }}
  • - {{ end}} -
+ {{ $bucket_display_name }} + +
    + {{ range .Documents }} +
  • {{ . }}
  • + {{ end}} +
{{ end }}