lot of new functionalities
This commit is contained in:
38
servers/web/api/auth.go
Normal file
38
servers/web/api/auth.go
Normal file
@@ -0,0 +1,38 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
func (h *Handler) OAuth2Callback(w http.ResponseWriter, r *http.Request) {
|
||||
code := r.URL.Query().Get("code")
|
||||
if code == "" {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
session, _ := h.idp.SessionsStore.Get(r, "parcoursmob_session")
|
||||
redirectSession := ""
|
||||
if session.Values["redirect"] != nil && session.Values["redirect"] != "" {
|
||||
redirectSession = session.Values["redirect"].(string)
|
||||
delete(session.Values, "redirect")
|
||||
}
|
||||
|
||||
result, err := h.applicationHandler.ProcessOAuth2Callback(code, redirectSession)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
session.Values["idtoken"] = result.IDToken
|
||||
|
||||
if err = session.Save(r, w); err != nil {
|
||||
log.Error().Err(err).Msg("Cannot save session")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
http.Redirect(w, r, result.RedirectURL, http.StatusFound)
|
||||
}
|
||||
48
servers/web/api/cache.go
Normal file
48
servers/web/api/cache.go
Normal file
@@ -0,0 +1,48 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"git.coopgo.io/coopgo-apps/parcoursmob/core/utils/cache"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
func (h *Handler) GetCache(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
cacheID := vars["cacheid"]
|
||||
|
||||
// Parse query parameters
|
||||
limitsMinStr := r.URL.Query().Get("limits.min")
|
||||
limitsMaxStr := r.URL.Query().Get("limits.max")
|
||||
limitsMin, limitsMax := cache.ParseLimits(limitsMinStr, limitsMaxStr)
|
||||
|
||||
// Use a channel to synchronize the goroutines
|
||||
ch := make(chan []byte)
|
||||
|
||||
// Fetch data from cache asynchronously
|
||||
go func() {
|
||||
result, err := h.cacheService.GetCacheData(cacheID, limitsMin, limitsMax)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Failed to get cache data")
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
ch <- nil
|
||||
return
|
||||
}
|
||||
ch <- result.Data // Signal that the data has been fetched successfully
|
||||
close(ch)
|
||||
}()
|
||||
|
||||
// Wait for the JSON marshaling goroutine to finish
|
||||
data := <-ch
|
||||
if data == nil {
|
||||
return // Stop processing if an error occurred
|
||||
}
|
||||
|
||||
// Send the JSON response to the client
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write(data)
|
||||
|
||||
<-ch
|
||||
}
|
||||
51
servers/web/api/calendars.go
Normal file
51
servers/web/api/calendars.go
Normal file
@@ -0,0 +1,51 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
func (h *Handler) CalendarGlobal(w http.ResponseWriter, r *http.Request) {
|
||||
enabled := h.config.GetBool("modules.agenda.enabled") && h.config.GetBool("modules.agenda.calendars.global.enabled")
|
||||
if !enabled {
|
||||
log.Error().Msg("global calendar not activated in configuration")
|
||||
w.WriteHeader(http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
result, err := h.applicationHandler.GenerateGlobalCalendar(r.Context())
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("error generating global calendar")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "text/calendar; charset=utf-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write([]byte(result.CalendarData))
|
||||
}
|
||||
|
||||
func (h *Handler) CalendarOrganizations(w http.ResponseWriter, r *http.Request) {
|
||||
enabled := h.config.GetBool("modules.agenda.enabled") && h.config.GetBool("modules.agenda.calendars.organizations.enabled")
|
||||
if !enabled {
|
||||
log.Error().Msg("organizations calendar not activated in configuration")
|
||||
w.WriteHeader(http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
vars := mux.Vars(r)
|
||||
groupID := vars["groupid"]
|
||||
|
||||
result, err := h.applicationHandler.GenerateOrganizationCalendar(r.Context(), groupID)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("error generating organization calendar")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "text/calendar; charset=utf-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write([]byte(result.CalendarData))
|
||||
}
|
||||
31
servers/web/api/export.go
Normal file
31
servers/web/api/export.go
Normal file
@@ -0,0 +1,31 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/csv"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
func (h *Handler) CacheExport(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
cacheID := vars["cacheid"]
|
||||
|
||||
result, err := h.applicationHandler.ExportCacheAsCSV(cacheID)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Error exporting cache")
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "text/csv")
|
||||
w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=export-%s.csv", cacheID))
|
||||
|
||||
csvWriter := csv.NewWriter(w)
|
||||
defer csvWriter.Flush()
|
||||
|
||||
csvWriter.Write(result.Headers)
|
||||
csvWriter.WriteAll(result.Values)
|
||||
}
|
||||
32
servers/web/api/geo.go
Normal file
32
servers/web/api/geo.go
Normal file
@@ -0,0 +1,32 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func (h *Handler) GeoAutocomplete(w http.ResponseWriter, r *http.Request) {
|
||||
t, ok := r.URL.Query()["text"]
|
||||
if !ok || len(t[0]) < 1 {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
text := t[0]
|
||||
|
||||
result, err := h.geoService.Autocomplete(text)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
j, err := json.Marshal(result.Features)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write(j)
|
||||
}
|
||||
37
servers/web/api/handler.go
Normal file
37
servers/web/api/handler.go
Normal file
@@ -0,0 +1,37 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"git.coopgo.io/coopgo-apps/parcoursmob/core/application"
|
||||
"git.coopgo.io/coopgo-apps/parcoursmob/core/utils/cache"
|
||||
"git.coopgo.io/coopgo-apps/parcoursmob/core/utils/geo"
|
||||
"git.coopgo.io/coopgo-apps/parcoursmob/core/utils/identification"
|
||||
cacheStorage "git.coopgo.io/coopgo-apps/parcoursmob/core/utils/storage"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
type Handler struct {
|
||||
config *viper.Viper
|
||||
idp *identification.IdentificationProvider
|
||||
applicationHandler *application.ApplicationHandler
|
||||
cacheService *cache.CacheService
|
||||
geoService *geo.GeoService
|
||||
}
|
||||
|
||||
func NewHandler(cfg *viper.Viper, idp *identification.IdentificationProvider, appHandler *application.ApplicationHandler, cacheHandler cacheStorage.CacheHandler) *Handler {
|
||||
cacheService := cache.NewCacheService(cacheHandler)
|
||||
geoService := geo.NewGeoService(cfg.GetString("geo.pelias.url"))
|
||||
|
||||
return &Handler{
|
||||
config: cfg,
|
||||
idp: idp,
|
||||
applicationHandler: appHandler,
|
||||
cacheService: cacheService,
|
||||
geoService: geoService,
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Handler) NotFound(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
}
|
||||
26
servers/web/api/protected/handler.go
Normal file
26
servers/web/api/protected/handler.go
Normal file
@@ -0,0 +1,26 @@
|
||||
package protected
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"git.coopgo.io/coopgo-apps/parcoursmob/core/application"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
type Handler struct {
|
||||
apiKey string
|
||||
config *viper.Viper
|
||||
applicationHandler *application.ApplicationHandler
|
||||
}
|
||||
|
||||
func NewHandler(cfg *viper.Viper, appHandler *application.ApplicationHandler) *Handler {
|
||||
return &Handler{
|
||||
apiKey: cfg.GetString("services.api.api_key"),
|
||||
config: cfg,
|
||||
applicationHandler: appHandler,
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Handler) NotFound(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
}
|
||||
29
servers/web/api/protected/users.go
Normal file
29
servers/web/api/protected/users.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package protected
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"git.coopgo.io/coopgo-platform/mobility-accounts/storage"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
func (h *Handler) RegisterUserHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
var user storage.Account
|
||||
if err := json.NewDecoder(r.Body).Decode(&user); err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
result, err := h.applicationHandler.RegisterUser(context.Background(), user)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Failed to register user")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
json.NewEncoder(w).Encode(result)
|
||||
}
|
||||
Reference in New Issue
Block a user