Merge branch 'main' into feature/responsive-header

This commit is contained in:
Alexel 2023-08-16 13:39:25 -04:00
commit d97d1ccf3c
8 changed files with 122 additions and 43 deletions

View file

@ -1,4 +1,4 @@
FROM golang:1.20.6 as build FROM golang:1.21.0 as build
LABEL author="Victor Lacasse-Beaudoin <vlbeaudoin@agecem.org>" LABEL author="Victor Lacasse-Beaudoin <vlbeaudoin@agecem.org>"
@ -24,9 +24,7 @@ RUN CGO_ENABLED=0 go build -a -installsuffix cgo -o agecem-org .
# Alpine # Alpine
FROM alpine:3.17.2 FROM alpine:3.18.3
RUN apk update && apk upgrade --no-cache
WORKDIR /app WORKDIR /app

View file

@ -96,7 +96,12 @@ func init() {
viper.BindPFlag("server.documents.use_ssl", serverCmd.Flags().Lookup("server-documents-use-ssl")) viper.BindPFlag("server.documents.use_ssl", serverCmd.Flags().Lookup("server-documents-use-ssl"))
// server.documents.buckets - --server-documents-buckets // 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")) viper.BindPFlag("server.documents.buckets", serverCmd.Flags().Lookup("server-documents-buckets"))
// server.api.auth - --server-api-auth // server.api.auth - --server-api-auth
@ -293,7 +298,7 @@ func handleDocumentation(c echo.Context) error {
return c.Render(http.StatusInternalServerError, "documentation-html", nil) return c.Render(http.StatusInternalServerError, "documentation-html", nil)
} }
var buckets []string var buckets map[string]string
err = json.Unmarshal(result, &buckets) err = json.Unmarshal(result, &buckets)
if err != nil { if err != nil {
@ -302,12 +307,13 @@ func handleDocumentation(c echo.Context) error {
type Bucket struct { type Bucket struct {
Name string Name string
DisplayName string
Documents []string Documents []string
} }
var data []Bucket var data []Bucket
for _, bucket := range buckets { for bucket, displayName := range buckets {
content, err := client.Call(http.MethodGet, fmt.Sprintf("/v1/bucket/%s", bucket)) content, err := client.Call(http.MethodGet, fmt.Sprintf("/v1/bucket/%s", bucket))
if err != nil { if err != nil {
return c.Render(http.StatusInternalServerError, "documentation-html", nil) return c.Render(http.StatusInternalServerError, "documentation-html", nil)
@ -340,6 +346,7 @@ func handleDocumentation(c echo.Context) error {
data = append(data, Bucket{ data = append(data, Bucket{
Name: bucket, Name: bucket,
DisplayName: displayName,
Documents: documents, Documents: documents,
}) })
} }
@ -381,10 +388,56 @@ func handleAdmin(c echo.Context) error {
} }
func handleAdminDocumentsUpload(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 { 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{ client, err := api.New(cfg.Server.Api.Protocol, cfg.Server.Api.Host, cfg.Server.Port, api.APIOptions{
KeyAuth: cfg.Server.Api.Auth, KeyAuth: cfg.Server.Api.Auth,
Key: cfg.Server.Api.Key, Key: cfg.Server.Api.Key,
@ -393,29 +446,52 @@ func handleAdminDocumentsUploadPOST(c echo.Context) error {
Password: cfg.Server.Admin.Password, Password: cfg.Server.Admin.Password,
}) })
if err != nil { 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") bucket := c.FormValue("bucket")
document, err := c.FormFile("document") document, err := c.FormFile("document")
if err != nil { 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) response, err := client.UploadDocument(bucket, document)
if err != nil { 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 // 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) info = fmt.Sprintf("[%.0f] /public/documentation/%s/%s", response.Info.Size, response.Info.Bucket, response.Info.Object)
status = response.Message 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)
} }

View file

@ -29,7 +29,7 @@ type Config struct {
} `mapstructure:"api"` } `mapstructure:"api"`
Documents struct { Documents struct {
AccessKeyId string `mapstructure:"access_key_id"` AccessKeyId string `mapstructure:"access_key_id"`
Buckets []string `mapstructure:"buckets"` Buckets map[string]string `mapstructure:"buckets"`
Endpoint string `mapstructure:"endpoint"` Endpoint string `mapstructure:"endpoint"`
SecretAccessKey string `mapstructure:"secret_access_key"` SecretAccessKey string `mapstructure:"secret_access_key"`
UseSSL bool `mapstructure:"use_ssl"` UseSSL bool `mapstructure:"use_ssl"`

View file

@ -35,8 +35,10 @@ server:
# #
# Also used to specify which buckets are to be created on receiving a POST request on /v1/seed # Also used to specify which buckets are to be created on receiving a POST request on /v1/seed
buckets: buckets:
- 'proces-verbaux' 'proces-verbaux': 'Procès-verbaux'
- 'politiques-et-reglements' 'politiques': 'Politiques'
'reglements': 'Règlements'
'formulaires': 'Formulaires'
api: api:
# Enable or disable key auth on /v1 routes # Enable or disable key auth on /v1 routes

View file

@ -58,7 +58,7 @@ func (m *MediaClient) Seed() ([]string, error) {
var new_buckets []string 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) exists, err := m.MinioClient.BucketExists(context.Background(), bucket)
if err != nil { if err != nil {
return new_buckets, err return new_buckets, err

View file

@ -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) exists, err := mediaClient.MinioClient.BucketExists(context.Background(), bucket_name)
if err != nil { if err != nil {
return c.JSON(http.StatusInternalServerError, "Error during minio#BucketExists") return c.JSON(http.StatusInternalServerError, "Error during minio#BucketExists")
} }
if exists { 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") bucket := c.Param("bucket")
allowed := false allowed := false
for _, bucket_allowed := range cfg.Server.Documents.Buckets { for bucket_allowed := range cfg.Server.Documents.Buckets {
if bucket == bucket_allowed { if bucket == bucket_allowed {
allowed = true allowed = true
} }
@ -171,7 +171,7 @@ func HandleV1DocumentCreate(c echo.Context) error {
} }
allowed := false allowed := false
for _, bucket_allowed := range cfg.Server.Documents.Buckets { for bucket_allowed := range cfg.Server.Documents.Buckets {
if bucket == bucket_allowed { if bucket == bucket_allowed {
allowed = true allowed = true
} }
@ -240,7 +240,7 @@ func HandleV1DocumentRead(c echo.Context) error {
document := c.Param("document") document := c.Param("document")
allowed := false allowed := false
for _, bucket_allowed := range cfg.Server.Documents.Buckets { for bucket_allowed := range cfg.Server.Documents.Buckets {
if bucket == bucket_allowed { if bucket == bucket_allowed {
allowed = true allowed = true
} }
@ -317,7 +317,7 @@ func HandleV1DocumentDelete(c echo.Context) error {
document := c.Param("document") document := c.Param("document")
allowed := false allowed := false
for _, bucket_allowed := range cfg.Server.Documents.Buckets { for bucket_allowed := range cfg.Server.Documents.Buckets {
if bucket == bucket_allowed { if bucket == bucket_allowed {
allowed = true allowed = true
} }

View file

@ -12,8 +12,9 @@
<form class="form adminUploadForm" action="/admin/documents/upload" method="post" enctype="multipart/form-data"> <form class="form adminUploadForm" action="/admin/documents/upload" method="post" enctype="multipart/form-data">
<label class="formLabel" for="bucket">Type de document:</label> <label class="formLabel" for="bucket">Type de document:</label>
<select class="formSelect" name="bucket" id="bucket"> <select class="formSelect" name="bucket" id="bucket">
<option class="formOption" value="proces-verbaux">Procès verbaux</option> {{ range .Buckets }}
<option class="formOption" value="politiques-et-reglements">Politiques et Règlements</option> <option class="formOption" value="{{ .Name }}">{{ .DisplayName }}</option>
{{ end }}
</select> </select>
<br> <br>
Document: <input class="formDocUpload" type="file" name="document"> Document: <input class="formDocUpload" type="file" name="document">

View file

@ -13,8 +13,10 @@
<p> <p>
{{ range . }} {{ range . }}
{{ $bucket_name := .Name }} {{ $bucket_name := .Name }}
{{ $bucket_display_name := .DisplayName }}
<details> <details>
<summary>{{ $bucket_name }}</summary> <summary>{{ $bucket_display_name }}</summary>
<ul> <ul>
{{ range .Documents }} {{ range .Documents }}
<li> <a href="/public/documentation/{{ $bucket_name }}/{{ . }}">{{ . }}</a></li> <li> <a href="/public/documentation/{{ $bucket_name }}/{{ . }}">{{ . }}</a></li>