fix/affichage-vie-etudiante #163
13 changed files with 278 additions and 417 deletions
|
@ -14,6 +14,8 @@ ADD api/ api/
|
|||
|
||||
ADD api_handlers/ api_handlers/
|
||||
|
||||
ADD apiresponse/ apiresponse/
|
||||
|
||||
ADD config/ config/
|
||||
|
||||
ADD media/ media/
|
||||
|
@ -24,6 +26,8 @@ ADD templates/ templates/
|
|||
|
||||
ADD web_handlers/ web_handlers/
|
||||
|
||||
Add webresponse/ webresponse/
|
||||
|
||||
RUN CGO_ENABLED=0 go build -a -installsuffix cgo -o agecem-org .
|
||||
|
||||
# Alpine
|
||||
|
|
218
api/api.go
218
api/api.go
|
@ -3,147 +3,44 @@ package api
|
|||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
"codeberg.org/vlbeaudoin/voki"
|
||||
"git.agecem.com/agecem/agecem-org/apiresponse"
|
||||
"git.agecem.com/agecem/agecem-org/config"
|
||||
"git.agecem.com/agecem/agecem-org/models"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
type API struct {
|
||||
Protocol string
|
||||
Host string
|
||||
Port int
|
||||
Opts APIOptions
|
||||
Voki *voki.Voki
|
||||
}
|
||||
|
||||
type APIOptions struct {
|
||||
KeyAuth bool
|
||||
Key string
|
||||
BasicAuth bool
|
||||
Username string
|
||||
Password string
|
||||
}
|
||||
|
||||
// NewApiClientFromViper returns a pointer to a new API object,
|
||||
// NewFromViper returns a pointer to a new API object,
|
||||
// provided the configuration options are managed by
|
||||
// https://git.agecem.com/agecem/agecem-org/config
|
||||
func NewApiClientFromViper() (*API, error) {
|
||||
func NewFromViper(client *http.Client) (api *API, err error) {
|
||||
var config config.Config
|
||||
|
||||
if err := viper.Unmarshal(&config); err != nil {
|
||||
if err = viper.Unmarshal(&config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
api, err := New(config.Server.Api.Protocol, config.Server.Api.Host, config.Server.Api.Port, APIOptions{
|
||||
KeyAuth: config.Server.Api.Auth,
|
||||
Key: config.Server.Api.Key,
|
||||
})
|
||||
if err != nil {
|
||||
return api, err
|
||||
}
|
||||
|
||||
return api, nil
|
||||
return New(client, config.Server.Api.Host, config.Server.Api.Key, config.Server.Api.Port, config.Server.Api.Protocol)
|
||||
}
|
||||
|
||||
func New(protocol, host string, port int, opts APIOptions) (*API, error) {
|
||||
api := API{
|
||||
Protocol: protocol,
|
||||
Host: host,
|
||||
Port: port,
|
||||
Opts: opts,
|
||||
}
|
||||
|
||||
return &api, nil
|
||||
func New(client *http.Client, host, key string, port int, protocol string) (*API, error) {
|
||||
return &API{Voki: voki.New(client, host, key, port, protocol)}, nil
|
||||
}
|
||||
|
||||
// Call returns a []byte representing a response body.
|
||||
// Can be used for GET or DELETE methods
|
||||
func (a *API) Call(method, route string) ([]byte, error) {
|
||||
func (a *API) UploadDocument(bucket string, file_header *multipart.FileHeader) (apiresponse.V1DocumentCreateResponse, error) {
|
||||
var response apiresponse.V1DocumentCreateResponse
|
||||
endpoint := fmt.Sprintf("%s://%s:%d",
|
||||
a.Protocol,
|
||||
a.Host,
|
||||
a.Port,
|
||||
)
|
||||
prerequest := fmt.Sprintf("%s%s", endpoint, route)
|
||||
request, err := url.QueryUnescape(prerequest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
switch method {
|
||||
case http.MethodGet:
|
||||
// Create client
|
||||
client := &http.Client{}
|
||||
|
||||
// Create request
|
||||
request, err := http.NewRequest(http.MethodGet, request, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if a.Opts.KeyAuth {
|
||||
request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", a.Opts.Key))
|
||||
}
|
||||
|
||||
// Fetch Request
|
||||
response, err := client.Do(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer response.Body.Close()
|
||||
|
||||
body, err := io.ReadAll(response.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return body, nil
|
||||
case http.MethodDelete:
|
||||
// Create client
|
||||
client := &http.Client{}
|
||||
|
||||
// Create request
|
||||
req, err := http.NewRequest(http.MethodDelete, request, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if a.Opts.KeyAuth {
|
||||
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", a.Opts.Key))
|
||||
}
|
||||
|
||||
// Fetch Request
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
// Read Response Body
|
||||
respBody, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return respBody, nil
|
||||
}
|
||||
|
||||
//return nil, errors.New(fmt.Sprintf("method must be 'GET' or 'DELETE', got '%s'", method))
|
||||
return nil, errors.New(fmt.Sprintf("method must be 'GET' or 'DELETE', got '%s'", method))
|
||||
}
|
||||
|
||||
func (a *API) UploadDocument(bucket string, file_header *multipart.FileHeader) (models.V1DocumentCreateResponse, error) {
|
||||
var response models.V1DocumentCreateResponse
|
||||
endpoint := fmt.Sprintf("%s://%s:%d",
|
||||
a.Protocol,
|
||||
a.Host,
|
||||
a.Port,
|
||||
a.Voki.Protocol,
|
||||
a.Voki.Host,
|
||||
a.Voki.Port,
|
||||
)
|
||||
|
||||
current_url := fmt.Sprintf("%s/v1/bucket/%s", endpoint, bucket)
|
||||
|
@ -187,8 +84,8 @@ func (a *API) UploadDocument(bucket string, file_header *multipart.FileHeader) (
|
|||
|
||||
req.Header.Set("Content-Type", writer.FormDataContentType())
|
||||
|
||||
if a.Opts.KeyAuth {
|
||||
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", a.Opts.Key))
|
||||
if a.Voki.Key != "" {
|
||||
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", a.Voki.Key))
|
||||
}
|
||||
|
||||
// Send the HTTP request
|
||||
|
@ -203,85 +100,6 @@ func (a *API) UploadDocument(bucket string, file_header *multipart.FileHeader) (
|
|||
return response, err
|
||||
}
|
||||
|
||||
// CallWithData takes data and returns a string representing a response body.
|
||||
// Can be used for POST or PUT methods
|
||||
func (a *API) CallWithData(method, route string, data []byte) (string, error) {
|
||||
endpoint := fmt.Sprintf("%s://%s:%d",
|
||||
a.Protocol,
|
||||
a.Host,
|
||||
a.Port,
|
||||
)
|
||||
request := fmt.Sprintf("%s%s", endpoint, route)
|
||||
|
||||
switch method {
|
||||
case http.MethodPost:
|
||||
// initialize http client
|
||||
client := &http.Client{}
|
||||
|
||||
// set the HTTP method, url, and request body
|
||||
req, err := http.NewRequest(http.MethodPost, request, bytes.NewBuffer(data))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if a.Opts.KeyAuth {
|
||||
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", a.Opts.Key))
|
||||
}
|
||||
|
||||
// set the request header Content-Type for json
|
||||
req.Header.Set("Content-Type", "application/json; charset=utf-8")
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
var res map[string]interface{}
|
||||
|
||||
json.NewDecoder(resp.Body).Decode(&res)
|
||||
return fmt.Sprintf("%s\n", res["message"]), nil
|
||||
/*
|
||||
case http.MethodPut:
|
||||
// initialize http client
|
||||
client := &http.Client{}
|
||||
|
||||
// set the HTTP method, url, and request body
|
||||
req, err := http.NewRequest(http.MethodPut, request, bytes.NewBuffer(data))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if a.Opts.KeyAuth {
|
||||
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", a.Opts.Key))
|
||||
}
|
||||
|
||||
// set the request header Content-Type for json
|
||||
//req.Header.Set("Content-Type", "application/json; charset=utf-8")
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
var res map[string]interface{}
|
||||
|
||||
json.NewDecoder(resp.Body).Decode(&res)
|
||||
return fmt.Sprintf("%s\n", res["message"]), nil
|
||||
*/
|
||||
}
|
||||
|
||||
//return "", errors.New(fmt.Sprintf("method must be 'POST' or 'PUT', got '%s'", method))
|
||||
return "", errors.New(fmt.Sprintf("method must be 'POST', got '%s'", method))
|
||||
}
|
||||
|
||||
func (a *API) ListBuckets() (models.V1BucketListResponse, error) {
|
||||
var response models.V1BucketListResponse
|
||||
result, err := a.Call(http.MethodGet, "/v1/bucket")
|
||||
if err != nil {
|
||||
return response, err
|
||||
}
|
||||
|
||||
if err = json.Unmarshal(result, &response); err != nil {
|
||||
return response, err
|
||||
}
|
||||
|
||||
return response, nil
|
||||
func (a *API) ListBuckets() (response apiresponse.V1BucketListResponse, err error) {
|
||||
return response, a.Voki.Unmarshal(http.MethodGet, "/v1/bucket", nil, true, &response)
|
||||
}
|
||||
|
|
|
@ -5,9 +5,9 @@ import (
|
|||
"net/http"
|
||||
"sort"
|
||||
|
||||
"git.agecem.com/agecem/agecem-org/apiresponse"
|
||||
"git.agecem.com/agecem/agecem-org/config"
|
||||
"git.agecem.com/agecem/agecem-org/media"
|
||||
"git.agecem.com/agecem/agecem-org/models"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/minio/minio-go/v7"
|
||||
)
|
||||
|
@ -30,7 +30,7 @@ func (h *V1Handler) HandleV1(c echo.Context) error {
|
|||
// HandleV1Seed créé des buckets dans minio selon la liste de buckets dans server.documents.buckets
|
||||
// Les buckets sont créés avec paramètres par défaut, et sont ensuite visible dans /v1/bucket.
|
||||
func (h *V1Handler) HandleV1Seed(c echo.Context) error {
|
||||
var response models.V1SeedResponse
|
||||
var response apiresponse.V1SeedResponse
|
||||
|
||||
new_buckets, err := h.MediaClient.Seed()
|
||||
response.Data.Buckets = new_buckets
|
||||
|
@ -56,7 +56,7 @@ func (h *V1Handler) HandleV1Seed(c echo.Context) error {
|
|||
|
||||
// HandleV1BucketList affiche les buckets permis par server.documents.buckets, qui existent.
|
||||
func (h *V1Handler) HandleV1BucketList(c echo.Context) error {
|
||||
var response models.V1BucketListResponse
|
||||
var response apiresponse.V1BucketListResponse
|
||||
|
||||
var buckets = make(map[string]string)
|
||||
|
||||
|
@ -83,7 +83,7 @@ func (h *V1Handler) HandleV1BucketList(c echo.Context) error {
|
|||
}
|
||||
|
||||
func (h *V1Handler) HandleV1BucketRead(c echo.Context) error {
|
||||
var response models.V1BucketReadResponse
|
||||
var response apiresponse.V1BucketReadResponse
|
||||
|
||||
bucket := c.Param("bucket")
|
||||
|
||||
|
@ -95,7 +95,7 @@ func (h *V1Handler) HandleV1BucketRead(c echo.Context) error {
|
|||
}
|
||||
|
||||
if !allowed {
|
||||
return c.JSON(models.NotFoundResponse())
|
||||
return c.JSON(apiresponse.NotFoundResponse())
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
|
@ -112,7 +112,7 @@ func (h *V1Handler) HandleV1BucketRead(c echo.Context) error {
|
|||
}
|
||||
|
||||
if !exists {
|
||||
return c.JSON(models.NotFoundResponse())
|
||||
return c.JSON(apiresponse.NotFoundResponse())
|
||||
}
|
||||
|
||||
objectCh := h.MediaClient.MinioClient.ListObjects(ctx, bucket, minio.ListObjectsOptions{})
|
||||
|
@ -137,7 +137,7 @@ func (h *V1Handler) HandleV1BucketRead(c echo.Context) error {
|
|||
|
||||
// HandleV1DocumentCreate permet d'ajouter un object dans un bucket, par multipart/form-data
|
||||
func (h *V1Handler) HandleV1DocumentCreate(c echo.Context) error {
|
||||
var response models.V1DocumentCreateResponse
|
||||
var response apiresponse.V1DocumentCreateResponse
|
||||
|
||||
bucket := c.Param("bucket")
|
||||
|
||||
|
@ -158,7 +158,7 @@ func (h *V1Handler) HandleV1DocumentCreate(c echo.Context) error {
|
|||
}
|
||||
|
||||
if !allowed {
|
||||
return c.JSON(models.NotFoundResponse())
|
||||
return c.JSON(apiresponse.NotFoundResponse())
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
|
@ -208,7 +208,7 @@ func (h *V1Handler) HandleV1DocumentRead(c echo.Context) error {
|
|||
}
|
||||
|
||||
if !allowed {
|
||||
return c.JSON(models.NotFoundResponse())
|
||||
return c.JSON(apiresponse.NotFoundResponse())
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
|
@ -221,7 +221,7 @@ func (h *V1Handler) HandleV1DocumentRead(c echo.Context) error {
|
|||
}
|
||||
|
||||
if !bucket_exists {
|
||||
return c.JSON(models.NotFoundResponse())
|
||||
return c.JSON(apiresponse.NotFoundResponse())
|
||||
}
|
||||
|
||||
document_info, err := h.MediaClient.MinioClient.StatObject(ctx, bucket, document, minio.StatObjectOptions{})
|
||||
|
@ -229,7 +229,7 @@ func (h *V1Handler) HandleV1DocumentRead(c echo.Context) error {
|
|||
if err != nil {
|
||||
if err.Error() == "The specified key does not exist." {
|
||||
|
||||
return c.JSON(models.NotFoundResponse())
|
||||
return c.JSON(apiresponse.NotFoundResponse())
|
||||
}
|
||||
|
||||
return c.JSON(http.StatusInternalServerError, map[string]interface{}{
|
||||
|
@ -253,7 +253,7 @@ func (h *V1Handler) HandleV1DocumentRead(c echo.Context) error {
|
|||
|
||||
// HandleV1DocumentUpdate permet de mettre à jour certains champs d'un object, comme le Content-Type ou le Filename
|
||||
func (h *V1Handler) HandleV1DocumentUpdate(c echo.Context) error {
|
||||
return c.JSON(models.NotImplementedResponse())
|
||||
return c.JSON(apiresponse.NotImplementedResponse())
|
||||
}
|
||||
|
||||
// HandleV1DocumentDelete permet de supprimer un object
|
||||
|
@ -269,7 +269,7 @@ func (h *V1Handler) HandleV1DocumentDelete(c echo.Context) error {
|
|||
}
|
||||
|
||||
if !allowed {
|
||||
return c.JSON(models.NotFoundResponse())
|
||||
return c.JSON(apiresponse.NotFoundResponse())
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
|
@ -282,14 +282,14 @@ func (h *V1Handler) HandleV1DocumentDelete(c echo.Context) error {
|
|||
}
|
||||
|
||||
if !bucket_exists {
|
||||
return c.JSON(models.NotFoundResponse())
|
||||
return c.JSON(apiresponse.NotFoundResponse())
|
||||
}
|
||||
|
||||
document_info, err := h.MediaClient.MinioClient.StatObject(ctx, bucket, document, minio.StatObjectOptions{})
|
||||
if err != nil {
|
||||
if err.Error() == "The specified key does not exist." {
|
||||
|
||||
return c.JSON(models.NotFoundResponse())
|
||||
return c.JSON(apiresponse.NotFoundResponse())
|
||||
}
|
||||
|
||||
return c.JSON(http.StatusInternalServerError, map[string]interface{}{
|
||||
|
|
45
apiresponse/apiresponse.go
Normal file
45
apiresponse/apiresponse.go
Normal file
|
@ -0,0 +1,45 @@
|
|||
package apiresponse
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type Responder interface {
|
||||
Respond() Responder
|
||||
}
|
||||
|
||||
type Response struct {
|
||||
StatusCode int `json:"status_code"`
|
||||
Message string
|
||||
Error string
|
||||
}
|
||||
|
||||
func (r Response) Respond() Responder {
|
||||
return r
|
||||
}
|
||||
|
||||
type SimpleResponse struct {
|
||||
Message string
|
||||
}
|
||||
|
||||
func (r SimpleResponse) Respond() Responder {
|
||||
return r
|
||||
}
|
||||
|
||||
func NotFoundResponse() (int, SimpleResponse) {
|
||||
return http.StatusNotFound, SimpleResponse{
|
||||
Message: "Not Found",
|
||||
}
|
||||
}
|
||||
|
||||
func NotImplementedResponse() (int, SimpleResponse) {
|
||||
return http.StatusNotImplemented, SimpleResponse{
|
||||
Message: "Not Implemented",
|
||||
}
|
||||
}
|
||||
|
||||
func InternalServerErrorResponse() (int, SimpleResponse) {
|
||||
return http.StatusInternalServerError, SimpleResponse{
|
||||
Message: "Internal Server Error",
|
||||
}
|
||||
}
|
15
apiresponse/bucket.go
Normal file
15
apiresponse/bucket.go
Normal file
|
@ -0,0 +1,15 @@
|
|||
package apiresponse
|
||||
|
||||
type V1BucketListResponse struct {
|
||||
Response
|
||||
Data struct {
|
||||
Buckets map[string]string
|
||||
}
|
||||
}
|
||||
|
||||
type V1BucketReadResponse struct {
|
||||
Response
|
||||
Data struct {
|
||||
Keys []string
|
||||
}
|
||||
}
|
10
apiresponse/document.go
Normal file
10
apiresponse/document.go
Normal file
|
@ -0,0 +1,10 @@
|
|||
package apiresponse
|
||||
|
||||
type V1DocumentCreateResponse struct {
|
||||
Response
|
||||
Data struct {
|
||||
Bucket string
|
||||
Key string
|
||||
Size int64
|
||||
}
|
||||
}
|
8
apiresponse/seed.go
Normal file
8
apiresponse/seed.go
Normal file
|
@ -0,0 +1,8 @@
|
|||
package apiresponse
|
||||
|
||||
type V1SeedResponse struct {
|
||||
Response
|
||||
Data struct {
|
||||
Buckets []string
|
||||
}
|
||||
}
|
102
cmd/server.go
102
cmd/server.go
|
@ -13,6 +13,7 @@ import (
|
|||
"io"
|
||||
"net/http"
|
||||
|
||||
"codeberg.org/vlbeaudoin/serpents"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
|
@ -69,9 +70,9 @@ func init() {
|
|||
publicFS = public.GetPublicFS()
|
||||
templatesFS = templates.GetTemplatesFS()
|
||||
|
||||
// server.port - --server-port
|
||||
serverCmd.Flags().Int("server-port", 8080, "Port to run the webserver on (config: server.port)")
|
||||
viper.BindPFlag("server.port", serverCmd.Flags().Lookup("server-port"))
|
||||
serpents.Int(serverCmd.Flags(),
|
||||
"server.port", "server-port", 8080,
|
||||
"Port to run the webserver on")
|
||||
|
||||
// Not currently used
|
||||
/*
|
||||
|
@ -80,62 +81,62 @@ func init() {
|
|||
viper.BindPFlag("server.documents.location", serverCmd.Flags().Lookup("server-documents-location"))
|
||||
*/
|
||||
|
||||
// server.documents.endpoint - --server-documents-endpoint
|
||||
serverCmd.Flags().String("server-documents-endpoint", "minio:9000", "Storage server endpoint (config: server.documents.endpoint)")
|
||||
viper.BindPFlag("server.documents.endpoint", serverCmd.Flags().Lookup("server-documents-endpoint"))
|
||||
serpents.String(serverCmd.Flags(),
|
||||
"server.documents.endpoint", "server-documents-endpoint", "minio:9000",
|
||||
"Storage server endpoint")
|
||||
|
||||
// server.documents.access_key_id - --server-documents-access-key-id
|
||||
serverCmd.Flags().String("server-documents-access-key-id", "agecem-org", "Storage server access key id (config: server.documents.access_key_id)")
|
||||
viper.BindPFlag("server.documents.access_key_id", serverCmd.Flags().Lookup("server-documents-access-key-id"))
|
||||
serpents.String(serverCmd.Flags(),
|
||||
"server.documents.access_key_id", "server-documents-access-key-id", "agecem-org",
|
||||
"Storage server access key id")
|
||||
|
||||
// server.documents.secret_access_key - --server-documents-secret-access-key
|
||||
serverCmd.Flags().String("server-documents-secret-access-key", "agecem-org", "Storage server secret access key (config: server.documents.secret_access_key)")
|
||||
viper.BindPFlag("server.documents.secret_access_key", serverCmd.Flags().Lookup("server-documents-secret-access-key"))
|
||||
serpents.String(serverCmd.Flags(),
|
||||
"server.documents.secret_access_key", "server-documents-secret-access-key", "agecem-org",
|
||||
"Storage server secret access key")
|
||||
|
||||
// server.documents.use_ssl - --server-documents-use-ssl
|
||||
serverCmd.Flags().Bool("server-documents-use-ssl", false, "Storage server SSL status (config: server.documents.use_ssl)")
|
||||
viper.BindPFlag("server.documents.use_ssl", serverCmd.Flags().Lookup("server-documents-use-ssl"))
|
||||
serpents.Bool(serverCmd.Flags(),
|
||||
"server.documents.use_ssl", "server-documents-use-ssl", false,
|
||||
"Storage server SSL status")
|
||||
|
||||
// server.documents.buckets - --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"))
|
||||
serpents.StringToString(serverCmd.Flags(),
|
||||
"server.documents.buckets", "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")
|
||||
|
||||
// server.api.auth - --server-api-auth
|
||||
serverCmd.Flags().Bool("server-api-auth", true, "Enable to allow key authentication for /v1 routes (config: server.api.auth)")
|
||||
viper.BindPFlag("server.api.auth", serverCmd.Flags().Lookup("server-api-auth"))
|
||||
serpents.Bool(serverCmd.Flags(),
|
||||
"server.api.auth", "server-api-auth", true,
|
||||
"Enable to allow key authentication for /v1 routes")
|
||||
|
||||
// server.api.key - --server-api-key
|
||||
serverCmd.Flags().String("server-api-key", "agecem-org", "Key to use for authenticating to /v1 routes")
|
||||
viper.BindPFlag("server.api.key", serverCmd.Flags().Lookup("server-api-key"))
|
||||
serpents.String(serverCmd.Flags(),
|
||||
"server.api.key", "server-api-key", "agecem-org",
|
||||
"Key to use for authenticating to /v1 routes")
|
||||
|
||||
// server.api.port
|
||||
serverCmd.Flags().Int("server-api-port", 8080, "API server port (config: server.api.port)")
|
||||
viper.BindPFlag("server.api.port", serverCmd.Flags().Lookup("server-api-port"))
|
||||
serpents.Int(serverCmd.Flags(),
|
||||
"server.api.port", "server-api-port", 8080,
|
||||
"API server port")
|
||||
|
||||
// server.api.protocol
|
||||
serverCmd.Flags().String("server-api-protocol", "http", "API server protocol (http/https) (config: server.api.protocol)")
|
||||
viper.BindPFlag("server.api.protocol", serverCmd.Flags().Lookup("server-api-protocol"))
|
||||
serpents.String(serverCmd.Flags(),
|
||||
"server.api.protocol", "server-api-protocol", "http",
|
||||
"API server protocol (http/https)")
|
||||
|
||||
// server.api.host
|
||||
serverCmd.Flags().String("server-api-host", "localhost", "API server host (config: server.api.host)")
|
||||
viper.BindPFlag("server.api.host", serverCmd.Flags().Lookup("server-api-host"))
|
||||
serpents.String(serverCmd.Flags(),
|
||||
"server.api.host", "server-api-host", "localhost",
|
||||
"API server host")
|
||||
|
||||
// server.admin.auth - --server-admin-auth
|
||||
serverCmd.Flags().Bool("server-admin-auth", true, "Enable to allow basic authentication for /admin routes (config: server.admin.auth)")
|
||||
viper.BindPFlag("server.admin.auth", serverCmd.Flags().Lookup("server-admin-auth"))
|
||||
serpents.Bool(serverCmd.Flags(),
|
||||
"server.admin.auth", "server-admin-auth", true,
|
||||
"Enable to allow basic authentication for /admin routes")
|
||||
|
||||
// server.admin.username - --server-admin-username
|
||||
serverCmd.Flags().String("server-admin-username", "agecem-org", "Username for basic authentication for /admin routes (config: server.admin.username)")
|
||||
viper.BindPFlag("server.admin.username", serverCmd.Flags().Lookup("server-admin-username"))
|
||||
serpents.String(serverCmd.Flags(),
|
||||
"server.admin.username", "server-admin-username", "agecem-org",
|
||||
"Username for basic authentication for /admin routes")
|
||||
|
||||
// server.admin.password - --server-admin-password
|
||||
serverCmd.Flags().String("server-admin-password", "agecem-org", "Password for basic authentication for /admin routes (config: server.admin.password)")
|
||||
viper.BindPFlag("server.admin.password", serverCmd.Flags().Lookup("server-admin-password"))
|
||||
serpents.String(serverCmd.Flags(),
|
||||
"server.admin.password", "server-admin-password", "agecem-org",
|
||||
"Password for basic authentication for /admin routes")
|
||||
}
|
||||
|
||||
func RunServer() {
|
||||
|
@ -226,9 +227,12 @@ func RunServer() {
|
|||
groupV1.DELETE("/bucket/:bucket/:document", v1Handler.HandleV1DocumentDelete)
|
||||
|
||||
// HTML Routes
|
||||
apiClient, err := api.NewApiClientFromViper()
|
||||
client := http.DefaultClient
|
||||
defer client.CloseIdleConnections()
|
||||
|
||||
apiClient, err := api.NewFromViper(client)
|
||||
if err != nil {
|
||||
log.Fatal("Error during NewMediaClientFromViper for API handlers")
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
webHandler := web_handlers.WebHandler{
|
||||
|
|
20
go.mod
20
go.mod
|
@ -1,12 +1,14 @@
|
|||
module git.agecem.com/agecem/agecem-org
|
||||
|
||||
go 1.19
|
||||
go 1.21.1
|
||||
|
||||
require (
|
||||
codeberg.org/vlbeaudoin/serpents v1.0.2
|
||||
codeberg.org/vlbeaudoin/voki v1.6.0
|
||||
github.com/labstack/echo/v4 v4.10.0
|
||||
github.com/minio/minio-go/v7 v7.0.52
|
||||
github.com/spf13/cobra v1.6.1
|
||||
github.com/spf13/viper v1.15.0
|
||||
github.com/spf13/viper v1.16.0
|
||||
)
|
||||
|
||||
require (
|
||||
|
@ -28,20 +30,20 @@ require (
|
|||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.0.6 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
|
||||
github.com/rs/xid v1.4.0 // indirect
|
||||
github.com/sirupsen/logrus v1.9.0 // indirect
|
||||
github.com/spf13/afero v1.9.3 // indirect
|
||||
github.com/spf13/cast v1.5.0 // indirect
|
||||
github.com/spf13/afero v1.9.5 // indirect
|
||||
github.com/spf13/cast v1.5.1 // indirect
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/subosito/gotenv v1.4.2 // indirect
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/valyala/fasttemplate v1.2.2 // indirect
|
||||
golang.org/x/crypto v0.6.0 // indirect
|
||||
golang.org/x/net v0.7.0 // indirect
|
||||
golang.org/x/sys v0.5.0 // indirect
|
||||
golang.org/x/text v0.7.0 // indirect
|
||||
golang.org/x/crypto v0.9.0 // indirect
|
||||
golang.org/x/net v0.10.0 // indirect
|
||||
golang.org/x/sys v0.8.0 // indirect
|
||||
golang.org/x/text v0.9.0 // indirect
|
||||
golang.org/x/time v0.2.0 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
|
|
57
go.sum
57
go.sum
|
@ -35,6 +35,10 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl
|
|||
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
||||
cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo=
|
||||
codeberg.org/vlbeaudoin/serpents v1.0.2 h1:mHuL+RBAMOGeiB5+ew1cRputEAnOIQNJW9o9a5Qjudo=
|
||||
codeberg.org/vlbeaudoin/serpents v1.0.2/go.mod h1:3bE/R0ToABwcUJtS1VcGEBa86K5FYhrZGAbFl2qL8kQ=
|
||||
codeberg.org/vlbeaudoin/voki v1.6.0 h1:Mm4K+SK5VmeWKnzUvcAkUxi2zcFQvzGX650Zi/FA7Iw=
|
||||
codeberg.org/vlbeaudoin/voki v1.6.0/go.mod h1:5XTLx/KiW/OfiupF3o7PAAAU/UhsPdKSrVMmtHbmkPI=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
|
@ -58,7 +62,8 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m
|
|||
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE=
|
||||
github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY=
|
||||
github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
||||
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
|
||||
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
|
@ -103,6 +108,7 @@ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
|||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
|
@ -145,10 +151,12 @@ github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZX
|
|||
github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
|
||||
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/labstack/echo/v4 v4.10.0 h1:5CiyngihEO4HXsz3vVsJn7f8xAlWwRr3aY6Ih280ZKA=
|
||||
github.com/labstack/echo/v4 v4.10.0/go.mod h1:S/T/5fy/GigaXnHTkh0ZGe4LpkkQysvRjFMSUTkDRNQ=
|
||||
github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8=
|
||||
|
@ -174,32 +182,33 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w
|
|||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU=
|
||||
github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek=
|
||||
github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ=
|
||||
github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k=
|
||||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||
github.com/rs/xid v1.4.0 h1:qd7wPTDkN6KQx2VmMBLrpHkiyQwgFXRnkOLacUiaSNY=
|
||||
github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
|
||||
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/spf13/afero v1.9.3 h1:41FoI0fD7OR7mGcKE/aOiLkGreyf8ifIOQmJANWogMk=
|
||||
github.com/spf13/afero v1.9.3/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y=
|
||||
github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
|
||||
github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU=
|
||||
github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM=
|
||||
github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ=
|
||||
github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA=
|
||||
github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48=
|
||||
github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA=
|
||||
github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY=
|
||||
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
|
||||
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v1.15.0 h1:js3yy885G8xwJa6iOISGFwd+qlUo5AvyXb7CiihdtiU=
|
||||
github.com/spf13/viper v1.15.0/go.mod h1:fFcTBJxvhhzSJiZy8n+PeW6t8l+KeT/uTARa0jHOQLA=
|
||||
github.com/spf13/viper v1.16.0 h1:rGGH0XDZhdUOryiDWjmIvUSWpbNqisK8Wk0Vyefw8hc=
|
||||
github.com/spf13/viper v1.16.0/go.mod h1:yg78JgCJcbrQOvV9YLXgkLaZqUidkY9K+Dd1FofRzQg=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
|
@ -210,8 +219,8 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5
|
|||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY=
|
||||
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8=
|
||||
github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0=
|
||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||
|
@ -235,9 +244,9 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U
|
|||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc=
|
||||
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
|
||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g=
|
||||
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
|
@ -302,8 +311,9 @@ golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwY
|
|||
golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
|
||||
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
|
@ -355,6 +365,7 @@ golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
|
@ -364,8 +375,8 @@ golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
|
@ -373,8 +384,10 @@ golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3
|
|||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
|
|
|
@ -1,92 +0,0 @@
|
|||
package models
|
||||
|
||||
import "net/http"
|
||||
|
||||
type Responder interface {
|
||||
Respond() Responder
|
||||
}
|
||||
|
||||
type Response struct {
|
||||
StatusCode int `json:"status_code"`
|
||||
Message string
|
||||
Error string
|
||||
}
|
||||
|
||||
func (r Response) Respond() Responder {
|
||||
return r
|
||||
}
|
||||
|
||||
type SimpleResponse struct {
|
||||
Message string
|
||||
}
|
||||
|
||||
func (r SimpleResponse) Respond() Responder {
|
||||
return r
|
||||
}
|
||||
|
||||
func NotFoundResponse() (int, SimpleResponse) {
|
||||
return http.StatusNotFound, SimpleResponse{
|
||||
Message: "Not Found",
|
||||
}
|
||||
}
|
||||
|
||||
func NotImplementedResponse() (int, SimpleResponse) {
|
||||
return http.StatusNotImplemented, SimpleResponse{
|
||||
Message: "Not Implemented",
|
||||
}
|
||||
}
|
||||
|
||||
type HandleAdminDocumentsUploadResponse struct {
|
||||
Response
|
||||
Data struct {
|
||||
Buckets []Bucket
|
||||
}
|
||||
}
|
||||
|
||||
type HandleDocumentationResponse struct {
|
||||
Response
|
||||
Data struct {
|
||||
Buckets []Bucket
|
||||
}
|
||||
}
|
||||
|
||||
type UploadDocumentResponse struct {
|
||||
Response
|
||||
Data UploadDocumentResponseData
|
||||
}
|
||||
|
||||
type UploadDocumentResponseData struct {
|
||||
Bucket string
|
||||
Object string
|
||||
Size float64
|
||||
}
|
||||
|
||||
type V1SeedResponse struct {
|
||||
Response
|
||||
Data struct {
|
||||
Buckets []string
|
||||
}
|
||||
}
|
||||
|
||||
type V1BucketListResponse struct {
|
||||
Response
|
||||
Data struct {
|
||||
Buckets map[string]string
|
||||
}
|
||||
}
|
||||
|
||||
type V1BucketReadResponse struct {
|
||||
Response
|
||||
Data struct {
|
||||
Keys []string
|
||||
}
|
||||
}
|
||||
|
||||
type V1DocumentCreateResponse struct {
|
||||
Response
|
||||
Data struct {
|
||||
Bucket string
|
||||
Key string
|
||||
Size int64
|
||||
}
|
||||
}
|
|
@ -1,13 +1,16 @@
|
|||
package web_handlers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"sort"
|
||||
|
||||
"git.agecem.com/agecem/agecem-org/api"
|
||||
"git.agecem.com/agecem/agecem-org/apiresponse"
|
||||
"git.agecem.com/agecem/agecem-org/models"
|
||||
"git.agecem.com/agecem/agecem-org/webresponse"
|
||||
"github.com/labstack/echo/v4"
|
||||
)
|
||||
|
||||
|
@ -48,13 +51,13 @@ func HandleVieEtudianteOrganisme(c echo.Context) error {
|
|||
}
|
||||
|
||||
func (h *WebHandler) HandleDocumentation(c echo.Context) error {
|
||||
var response models.HandleDocumentationResponse
|
||||
var response webresponse.HandleDocumentationResponse
|
||||
|
||||
v1BucketListResponse, err := h.ApiClient.ListBuckets()
|
||||
if err != nil {
|
||||
response.StatusCode = v1BucketListResponse.StatusCode
|
||||
response.Message = v1BucketListResponse.Message
|
||||
response.Error = err.Error()
|
||||
response.Message = v1BucketListResponse.Message
|
||||
response.StatusCode = v1BucketListResponse.StatusCode
|
||||
|
||||
return c.Render(response.StatusCode, "documentation-html", response)
|
||||
}
|
||||
|
@ -63,24 +66,14 @@ func (h *WebHandler) HandleDocumentation(c echo.Context) error {
|
|||
|
||||
for bucket, displayName := range v1BucketListResponse.Data.Buckets {
|
||||
// TODO move call to dedicated API client method
|
||||
content, err := h.ApiClient.Call(http.MethodGet, fmt.Sprintf("/v1/bucket/%s", bucket))
|
||||
if err != nil {
|
||||
response.StatusCode = http.StatusInternalServerError
|
||||
response.Message = "Error during /v1/bucket/:bucket"
|
||||
var v1BucketReadResponse apiresponse.V1BucketReadResponse
|
||||
|
||||
if err = h.ApiClient.Voki.Unmarshal(http.MethodGet, fmt.Sprintf("/v1/bucket/%s", bucket), nil, true, &v1BucketReadResponse); err != nil {
|
||||
response.Error = err.Error()
|
||||
|
||||
return c.Render(response.StatusCode, "documentation-html", response)
|
||||
}
|
||||
|
||||
var v1BucketReadResponse models.V1BucketReadResponse
|
||||
|
||||
err = json.Unmarshal(content, &v1BucketReadResponse)
|
||||
if err != nil {
|
||||
response.StatusCode = http.StatusInternalServerError
|
||||
response.Message = "Error during json.Unmarshal /v1/bucket/:bucket"
|
||||
response.Error = err.Error()
|
||||
response.StatusCode = http.StatusInternalServerError
|
||||
|
||||
return c.Render(response.StatusCode, "documentation-html", response)
|
||||
return c.Render(http.StatusOK, "documentation-html", response)
|
||||
}
|
||||
|
||||
response.Data.Buckets = append(response.Data.Buckets, models.Bucket{
|
||||
|
@ -96,7 +89,7 @@ func (h *WebHandler) HandleDocumentation(c echo.Context) error {
|
|||
//response.Message = "HandleDocumentation ok"
|
||||
|
||||
// TODO render .Message
|
||||
return c.Render(response.StatusCode, "documentation-html", response)
|
||||
return c.Render(http.StatusOK, "documentation-html", response)
|
||||
//return c.Render(response.StatusCode, "documentation-html", response.Data.Buckets)
|
||||
}
|
||||
|
||||
|
@ -108,20 +101,30 @@ func (h *WebHandler) HandlePublicDocumentation(c echo.Context) error {
|
|||
bucket := c.Param("bucket")
|
||||
document := c.Param("document")
|
||||
|
||||
result, err := h.ApiClient.Call(http.MethodGet, fmt.Sprintf("/v1/bucket/%s/%s", bucket, document))
|
||||
unescaped, err := url.QueryUnescape(fmt.Sprintf("/v1/bucket/%s/%s", bucket, document))
|
||||
if err != nil {
|
||||
return c.JSON(models.NotFoundResponse())
|
||||
return c.JSON(http.StatusBadRequest, map[string]string{"message": "Bad Request"})
|
||||
}
|
||||
|
||||
// Check if result can fit inside a map containing a message
|
||||
var result_map map[string]string
|
||||
response, err := h.ApiClient.Voki.Call(http.MethodGet, unescaped, nil, true)
|
||||
if err != nil {
|
||||
return c.JSON(apiresponse.NotFoundResponse())
|
||||
}
|
||||
defer response.Body.Close()
|
||||
|
||||
err = json.Unmarshal(result, &result_map)
|
||||
if err == nil {
|
||||
return c.JSON(http.StatusBadRequest, result_map)
|
||||
switch response.StatusCode {
|
||||
case http.StatusNotFound:
|
||||
return c.JSON(apiresponse.NotFoundResponse())
|
||||
case http.StatusInternalServerError:
|
||||
return c.JSON(http.StatusInternalServerError, map[string]string{"message": "Internal Server Error"})
|
||||
}
|
||||
|
||||
return c.Blob(http.StatusOK, "application/octet-stream", result)
|
||||
body, err := io.ReadAll(response.Body)
|
||||
if err != nil {
|
||||
return c.JSON(http.StatusInternalServerError, map[string]string{"message": "Internal Server Error"})
|
||||
}
|
||||
|
||||
return c.Blob(http.StatusOK, "application/octet-stream", body)
|
||||
}
|
||||
|
||||
func HandleAdmin(c echo.Context) error {
|
||||
|
@ -129,7 +132,7 @@ func HandleAdmin(c echo.Context) error {
|
|||
}
|
||||
|
||||
func (h *WebHandler) HandleAdminDocumentsUpload(c echo.Context) error {
|
||||
var response models.HandleAdminDocumentsUploadResponse
|
||||
var response webresponse.HandleAdminDocumentsUploadResponse
|
||||
|
||||
v1BucketListResponse, err := h.ApiClient.ListBuckets()
|
||||
if err != nil {
|
||||
|
@ -152,7 +155,7 @@ func (h *WebHandler) HandleAdminDocumentsUpload(c echo.Context) error {
|
|||
}
|
||||
|
||||
func (h *WebHandler) HandleAdminDocumentsUploadPOST(c echo.Context) error {
|
||||
var response models.HandleAdminDocumentsUploadResponse
|
||||
var response webresponse.HandleAdminDocumentsUploadResponse
|
||||
|
||||
v1BucketListResponse, err := h.ApiClient.ListBuckets()
|
||||
if err != nil {
|
||||
|
|
31
webresponse/webresponse.go
Normal file
31
webresponse/webresponse.go
Normal file
|
@ -0,0 +1,31 @@
|
|||
package webresponse
|
||||
|
||||
import (
|
||||
"git.agecem.com/agecem/agecem-org/apiresponse"
|
||||
"git.agecem.com/agecem/agecem-org/models"
|
||||
)
|
||||
|
||||
type HandleAdminDocumentsUploadResponse struct {
|
||||
apiresponse.Response
|
||||
Data struct {
|
||||
Buckets []models.Bucket
|
||||
}
|
||||
}
|
||||
|
||||
type HandleDocumentationResponse struct {
|
||||
apiresponse.Response
|
||||
Data struct {
|
||||
Buckets []models.Bucket
|
||||
}
|
||||
}
|
||||
|
||||
type UploadDocumentResponse struct {
|
||||
apiresponse.Response
|
||||
Data UploadDocumentResponseData
|
||||
}
|
||||
|
||||
type UploadDocumentResponseData struct {
|
||||
Bucket string
|
||||
Object string
|
||||
Size float64
|
||||
}
|
Loading…
Reference in a new issue