Mercurial > gemma
view pkg/controllers/routes.go @ 5718:3d497077f888 uploadwg
Implemented direct file upload as alternative import method for WG.
For testing and data corrections it is useful to be able to import
waterway gauges data directly by uploading a xml file.
author | Sascha Wilde <wilde@sha-bang.de> |
---|---|
date | Thu, 18 Apr 2024 19:23:19 +0200 |
parents | 6270951dda28 |
children |
line wrap: on
line source
// This is Free Software under GNU Affero General Public License v >= 3.0 // without warranty, see README.md and license for details. // // SPDX-License-Identifier: AGPL-3.0-or-later // License-Filename: LICENSES/AGPL-3.0.txt // // Copyright (C) 2018, 2020 by via donau // – Österreichische Wasserstraßen-Gesellschaft mbH // Software engineering by Intevation GmbH // // Author(s): // * Sascha L. Teichmann <sascha.teichmann@intevation.de> // * Sascha Wilde <sascha.wilde@intevation.de> package controllers import ( "encoding/json" "net/http" "net/http/httputil" "strings" "github.com/gorilla/mux" "gemma.intevation.de/gemma/pkg/auth" "gemma.intevation.de/gemma/pkg/imports" mw "gemma.intevation.de/gemma/pkg/middleware" "gemma.intevation.de/gemma/pkg/models" ) // BindRoutes binds all the API endpoints to the exposed router. func BindRoutes(m *mux.Router) { api := m.PathPrefix("/api").Subrouter() var ( sysAdmin = auth.EnsureRole("sys_admin") waterwayAdmin = auth.EnsureRole("waterway_admin") anyUser = auth.EnsureRole("sys_admin", "waterway_admin", "waterway_user") ) // Password resets. api.Handle("/users/passwordreset", &mw.JSONHandler{ Input: func(*http.Request) any { return new(models.PWResetUser) }, Handle: passwordResetRequest, NoConn: true, }).Methods(http.MethodPost) api.HandleFunc("/users/passwordreset/{hash}", passwordReset). Methods(http.MethodGet) // User management. api.Handle("/users", anyUser(&mw.JSONHandler{ Handle: listUsers, })).Methods(http.MethodGet) api.Handle("/users", sysAdmin(&mw.JSONHandler{ Input: func(*http.Request) any { return new(models.User) }, Handle: createUser, })).Methods(http.MethodPost) api.Handle("/users/{user:.+}", anyUser(&mw.JSONHandler{ Handle: listUser, })).Methods(http.MethodGet) api.Handle("/users/{user:.+}", anyUser(&mw.JSONHandler{ Input: func(*http.Request) any { return new(models.User) }, Handle: updateUser, })).Methods(http.MethodPut) api.Handle("/users/{user:.+}", anyUser(&mw.JSONHandler{ Input: func(*http.Request) any { return new(models.UserPatch) }, Handle: patchUser, })).Methods(http.MethodPatch) api.Handle("/users/{user:.+}", sysAdmin(&mw.JSONHandler{ Handle: deleteUser, })).Methods(http.MethodDelete) // System notifications api.Handle("/testmail/{user:.+}", sysAdmin(&mw.JSONHandler{ Handle: sendTestMail, })).Methods(http.MethodGet) // System Management api.Handle("/system/log/{service}/{file}", sysAdmin(&mw.JSONHandler{ Handle: showSystemLog, NoConn: true, })).Methods(http.MethodGet) // System Settings api.Handle("/system/config", anyUser(&mw.JSONHandler{ Handle: getSystemConfig, NoConn: true, })).Methods(http.MethodGet) api.Handle("/system/settings", anyUser(&mw.JSONHandler{ Handle: getSystemSettings, })).Methods(http.MethodGet) api.Handle("/system/settings", sysAdmin(&mw.JSONHandler{ Input: func(*http.Request) any { return &map[string]string{} }, Handle: setSystemSettings, })).Methods(http.MethodPut) // Print templates api.Handle("/templates", anyUser(&mw.JSONHandler{ Handle: listPrintTemplates, })).Methods(http.MethodGet) tTypes := "{type:" + strings.Join(templateTypes, "|") + "}" api.Handle("/templates/"+tTypes, anyUser(&mw.JSONHandler{ Handle: listPrintTemplates, })).Methods(http.MethodGet) api.Handle("/templates/"+tTypes+"/{name}", anyUser(&mw.JSONHandler{ Handle: fetchPrintTemplate, })).Methods(http.MethodGet) api.Handle("/templates/"+tTypes+"/{name}", waterwayAdmin(&mw.JSONHandler{ Input: func(*http.Request) any { return &json.RawMessage{} }, Handle: createPrintTemplate, Limit: maxPrintTemplateSize, })).Methods(http.MethodPost) api.Handle("/templates/"+tTypes+"/{name}", waterwayAdmin(&mw.JSONHandler{ Handle: deletePrintTemplate, })).Methods(http.MethodDelete) api.Handle("/templates/"+tTypes+"/{name}", waterwayAdmin(&mw.JSONHandler{ Input: func(*http.Request) any { return &json.RawMessage{} }, Handle: updatePrintTemplate, Limit: maxPrintTemplateSize, })).Methods(http.MethodPatch) // External proxies. external := mw.NotFound(&httputil.ReverseProxy{ Director: proxyDirector(models.ExternalServices.Find), ModifyResponse: proxyModifyResponse("/api/external/"), }) externalAuth := anyUser(external) api.Handle("/external/{hash}/{url}", externalAuth). Methods( http.MethodGet, http.MethodPost, http.MethodPut, http.MethodDelete) api.Handle("/external/{entry}", externalAuth). Methods( http.MethodGet, http.MethodPost, http.MethodPut, http.MethodDelete) // Internal proxies. internal := mw.NotFound(&httputil.ReverseProxy{ Director: proxyDirector(models.InternalServices.Find), ModifyResponse: proxyModifyResponse("/api/internal/"), }) internalAuth := anyUser( mw.ModifyQuery(internal, mw.InjectUser)) api.Handle("/internal/{hash}/{url}", internalAuth). Methods( http.MethodGet, http.MethodPost, http.MethodPut, http.MethodDelete) api.Handle("/internal/{entry}", internalAuth). Methods( http.MethodGet, http.MethodPost, http.MethodPut, http.MethodDelete) api.Handle("/published", anyUser(&mw.JSONHandler{ Handle: published, NoConn: true, })).Methods(http.MethodGet) // Survey selection api.Handle("/surveys", anyUser(&mw.JSONHandler{ Handle: listSurveys, })).Methods(http.MethodGet).Queries("id", "{id}") api.Handle("/surveys", anyUser(&mw.JSONHandler{ Handle: listSurveys, })).Methods(http.MethodGet).Queries("name", "{name}", "date", "{date}") // difference calculation api.Handle("/diff", anyUser(&mw.JSONHandler{ Input: func(*http.Request) any { return new(models.DiffCalculationInput) }, Handle: diffCalculation, NoConn: true, })).Methods(http.MethodPost) // Cross sections api.Handle("/cross", anyUser(&mw.JSONHandler{ Input: func(*http.Request) any { return new(models.CrossSectionInput) }, Handle: crossSection, })).Methods(http.MethodPost) // Feature search api.Handle("/search", anyUser(&mw.JSONHandler{ Input: func(*http.Request) any { return new(models.SearchRequest) }, Handle: searchFeature, })).Methods(http.MethodPost) // Geo styling api.Handle("/geo/style/{feature}", sysAdmin(http.HandlerFunc(uploadStyle))).Methods(http.MethodPost) // Imports api.Handle("/imports/sr-upload/{token}", waterwayAdmin(http.HandlerFunc(deleteSoundingUpload))).Methods(http.MethodDelete) api.Handle("/imports/sr-upload", waterwayAdmin(&mw.JSONHandler{ Handle: uploadSoundingResult, })).Methods(http.MethodPost) api.Handle("/imports/sr", waterwayAdmin( http.HandlerFunc(importSoundingResult))).Methods(http.MethodPost) api.Handle("/imports/wp", waterwayAdmin( importWaterwayProfiles())).Methods(http.MethodPost) api.Handle("/imports/agm", waterwayAdmin( importApprovedGaugeMeasurements())).Methods(http.MethodPost) api.Handle("/imports/ubn", waterwayAdmin( importUploadedBottleneck())).Methods(http.MethodPost) api.Handle("/imports/ufa", waterwayAdmin( importUploadedFairwayAvailability())).Methods(http.MethodPost) api.Handle("/imports/ugm", waterwayAdmin( importUploadedGaugeMeasurement())).Methods(http.MethodPost) api.Handle("/imports/uwg", waterwayAdmin( importUploadedWaterwayGauge())).Methods(http.MethodPost) api.Handle("/imports/stsh", sysAdmin( importUploadedStretchShape())).Methods(http.MethodPost) api.Handle("/imports/{kind:st}", sysAdmin(&mw.JSONHandler{ Input: importModel, Handle: manualImport, NoConn: true, })).Methods(http.MethodPost) kinds := strings.Join([]string{ "bn", "gm", "fa", "wx", "wa", "wg", "dmv", "fd", "dma", "sec", "dsec", "dst", "dsr", "fm_bcnlat_hydro", "fm_bcnlat_ienc", "fm_boycar", "fm_boylat_hydro", "fm_boylat_ienc", "fm_boysaw", "fm_boyspp", "fm_daymar_hydro", "fm_daymar_ienc", "fm_lights", "fm_rtpbcn", "fm_topmar", "fm_notmrk", }, "|") api.Handle("/imports/{kind:"+kinds+"}", waterwayAdmin(&mw.JSONHandler{ Input: importModel, Handle: manualImport, NoConn: true, })).Methods(http.MethodPost) api.Handle("/imports/{kind:report|statsupdate}", sysAdmin(&mw.JSONHandler{ Input: importModel, Handle: manualImport, NoConn: true, })).Methods(http.MethodPost) // Import scheduler configuration api.Handle("/imports/config/{id:[0-9]+}/run", waterwayAdmin(&mw.JSONHandler{ Handle: runImportConfig, })).Methods(http.MethodGet) api.Handle("/imports/config/{id:[0-9]+}", waterwayAdmin(&mw.JSONHandler{ Input: func(*http.Request) any { return &json.RawMessage{} }, Handle: modifyImportConfig, })).Methods(http.MethodPatch) api.Handle("/imports/config/{id:[0-9]+}", waterwayAdmin(&mw.JSONHandler{ Handle: deleteImportConfig, })).Methods(http.MethodDelete) api.Handle("/imports/config/{id:[0-9]+}", waterwayAdmin(&mw.JSONHandler{ Handle: infoImportConfig, })).Methods(http.MethodGet) api.Handle("/imports/config", waterwayAdmin(&mw.JSONHandler{ Input: func(*http.Request) any { return new(imports.ImportConfigIn) }, Handle: addImportConfig, })).Methods(http.MethodPost) api.Handle("/imports/config", waterwayAdmin(&mw.JSONHandler{ Handle: listImportConfigs, })).Methods(http.MethodGet) // Import queue api.Handle("/imports", waterwayAdmin(&mw.JSONHandler{ Handle: listImports, })).Methods(http.MethodGet) api.Handle("/imports/export", waterwayAdmin( mw.DBConn(http.HandlerFunc(exportImports)))).Methods(http.MethodGet) api.Handle("/imports/{id:[0-9]+}", waterwayAdmin(&mw.JSONHandler{ Handle: importLogs, })).Methods(http.MethodGet) api.Handle("/imports", waterwayAdmin(&mw.JSONHandler{ Input: func(*http.Request) any { return &[]models.Review{} }, Handle: reviewImports, NoConn: true, })).Methods(http.MethodPatch) api.Handle("/imports/{id:[0-9]+}", waterwayAdmin(&mw.JSONHandler{ Handle: deleteImport, })).Methods(http.MethodDelete) // Handler to review an import which is pending. api.Handle("/imports/{id:[0-9]+}/{state:(?:accepted|declined)}", waterwayAdmin(&mw.JSONHandler{ Handle: reviewImport, NoConn: true, })).Methods(http.MethodPut) // Handler for reporting api.Handle("/data/reports", anyUser(&mw.JSONHandler{ Handle: listReports, NoConn: true, })).Methods(http.MethodGet) api.Handle("/data/report/{name:"+models.SafePathExp+"}", waterwayAdmin( mw.DBConn(http.HandlerFunc(report)))).Methods(http.MethodGet) // Handler for update scripts api.Handle("/data/stats-updates", sysAdmin(&mw.JSONHandler{ Handle: listStatsUpdates, })).Methods(http.MethodGet) api.Handle("/data/stats-updates/{name:.+}", sysAdmin(&mw.JSONHandler{ Handle: statsUpdates, })).Methods(http.MethodGet) // Handler to serve data to the client. api.Handle("/data/{type:availability|fairway}/{kind:stretch|section|bottleneck}/{name:.+}", anyUser( mw.DBConn(http.HandlerFunc(fairwayAvailability)))).Methods(http.MethodGet) api.Handle("/data/stretch/shape/{name:.+}", anyUser( mw.DBConn(http.HandlerFunc(stretchShapeDownload)))).Methods(http.MethodGet) api.Handle("/data/waterlevels/{gauge:.+}", anyUser( mw.DBConn(http.HandlerFunc(waterlevels)))).Methods(http.MethodGet) api.Handle("/data/longterm-waterlevels/{gauge:.+}", anyUser( mw.DBConn(http.HandlerFunc(longtermWaterlevels)))).Methods(http.MethodGet) // TODO: gauge should not contain '/'s. api.Handle("/data/year-waterlevels/{gauge}/{year:[0-9]+}", anyUser( mw.DBConn(http.HandlerFunc(yearWaterlevels)))).Methods(http.MethodGet) api.Handle("/data/nash-sutcliffe/{gauge:.+}", anyUser(&mw.JSONHandler{ Handle: nashSutcliffe, })).Methods(http.MethodGet) // Token handling: Login/Logout. api.HandleFunc("/login", login). Methods(http.MethodPost) api.Handle("/logout", auth.SessionMiddleware(http.HandlerFunc(logout))). Methods(http.MethodGet, http.MethodPost) api.Handle("/renew", auth.SessionMiddleware(http.HandlerFunc(renew))). Methods(http.MethodGet, http.MethodPost) }