view pkg/controllers/routes.go @ 2006:35acb7f9ae0c

Do anything else before expectedly failing role creation Creating roles during database setup expectedly fails in case there already is another gemma database in the cluster. Doing it at the end of the transaction ensures it does not hide errors in other commands in the script. In passing, add the default admin via the designated view to ensure it will become a correctly set up application user.
author Tom Gottfried <tom@intevation.de>
date Thu, 24 Jan 2019 17:23:43 +0100
parents 71b722809b2b
children 42a33f9e1f95
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 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 (
	"net/http"
	"net/http/httputil"

	"github.com/gorilla/mux"

	"gemma.intevation.de/gemma/pkg/auth"
	"gemma.intevation.de/gemma/pkg/imports"
	"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")
		any           = auth.EnsureRole("sys_admin", "waterway_admin", "waterway_user")
	)

	// User management.
	api.Handle("/users", any(&JSONHandler{
		Handle: listUsers,
	})).Methods(http.MethodGet)

	api.Handle("/users", sysAdmin(&JSONHandler{
		Input:  func() interface{} { return new(models.User) },
		Handle: createUser,
	})).Methods(http.MethodPost)

	api.Handle("/users/{user}", any(&JSONHandler{
		Handle: listUser,
	})).Methods(http.MethodGet)

	api.Handle("/users/{user}", any(&JSONHandler{
		Input:  func() interface{} { return new(models.User) },
		Handle: updateUser,
	})).Methods(http.MethodPut)

	api.Handle("/users/{user}", sysAdmin(&JSONHandler{
		Handle: deleteUser,
	})).Methods(http.MethodDelete)

	// System notifications
	api.Handle("/testmail/{user}", sysAdmin(&JSONHandler{
		Handle: sendTestMail,
	})).Methods(http.MethodGet)

	// System Management
	api.Handle("/system/log/{service}/{file}", sysAdmin(&JSONHandler{
		Handle: showSystemLog,
		NoConn: true,
	})).Methods(http.MethodGet)

	// System Settings
	api.Handle("/system/style/{feature}/{attr}", any(&JSONHandler{
		Handle: getFeatureStyle,
	})).Methods(http.MethodGet)

	api.Handle("/system/style/{feature}/{attr}", any(&JSONHandler{
		Input:  func() interface{} { return new(models.Colour) },
		Handle: setFeatureStyle,
	})).Methods(http.MethodPut)

	// Password resets.
	api.Handle("/users/passwordreset", &JSONHandler{
		Input:  func() interface{} { return new(models.PWResetUser) },
		Handle: passwordResetRequest,
		NoConn: true,
	}).Methods(http.MethodPost)

	api.Handle("/users/passwordreset/{hash}", &JSONHandler{
		Handle: passwordReset,
		NoConn: true,
	}).Methods(http.MethodGet)

	// External proxies.
	external := middleware.NotFound(&httputil.ReverseProxy{
		Director:       proxyDirector(models.ExternalServices.Find),
		ModifyResponse: proxyModifyResponse("/api/external/"),
	})

	externalAuth := any(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 := middleware.NotFound(&httputil.ReverseProxy{
		Director:       proxyDirector(models.InternalServices.Find),
		ModifyResponse: proxyModifyResponse("/api/internal/"),
	})

	internalAuth := any(
		middleware.ModifyQuery(internal, middleware.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", any(&JSONHandler{
		Handle: published,
		NoConn: true,
	})).Methods(http.MethodGet)

	// Survey selection
	api.Handle("/surveys/{bottleneck}", any(&JSONHandler{
		Handle: listSurveys,
	})).Methods(http.MethodGet)

	// Bottlenecks
	api.Handle("/bottlenecks", any(&JSONHandler{
		Handle: listBottlenecks,
	})).Methods(http.MethodGet)

	// Cross sections
	api.Handle("/cross", any(&JSONHandler{
		Input:  func() interface{} { return new(models.CrossSectionInput) },
		Handle: crossSection,
	})).Methods(http.MethodPost)

	// Feature search
	api.Handle("/search", any(&JSONHandler{
		Input:  func() interface{} { 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/soundingresult-upload/{token}",
		waterwayAdmin(http.HandlerFunc(deleteSoundingUpload))).Methods(http.MethodDelete)

	api.Handle("/imports/soundingresult-upload", waterwayAdmin(&JSONHandler{
		Handle: uploadSoundingResult,
	})).Methods(http.MethodPost)

	api.Handle("/imports/soundingresult", waterwayAdmin(
		http.HandlerFunc(importSoundingResult))).Methods(http.MethodPost)

	api.Handle("/imports/approvedgm", waterwayAdmin(
		http.HandlerFunc(importApprovedGaugeMeasurements))).Methods(http.MethodPost)

	api.Handle("/imports/bottleneck", waterwayAdmin(&JSONHandler{
		Input:  func() interface{} { return new(models.BottleneckImport) },
		Handle: manualImport(imports.BNJobKind, importBottleneck),
		NoConn: true,
	})).Methods(http.MethodPost)

	api.Handle("/imports/gaugemeasurement", waterwayAdmin(&JSONHandler{
		Input:  func() interface{} { return new(models.GaugeMeasurementImport) },
		Handle: manualImport(imports.GMJobKind, importGaugeMeasurement),
		NoConn: true,
	})).Methods(http.MethodPost)

	api.Handle("/imports/fairwayavailability", waterwayAdmin(&JSONHandler{
		Input:  func() interface{} { return new(models.FairwayAvailabilityImport) },
		Handle: manualImport(imports.FAJobKind, importFairwayAvailability),
		NoConn: true,
	})).Methods(http.MethodPost)

	api.Handle("/imports/waterwayaxis", waterwayAdmin(&JSONHandler{
		Input:  func() interface{} { return new(models.WaterwayAxisImport) },
		Handle: manualImport(imports.WXJobKind, importWaterwayAxis),
		NoConn: true,
	})).Methods(http.MethodPost)

	api.Handle("/imports/waterwayarea", waterwayAdmin(&JSONHandler{
		Input:  func() interface{} { return new(models.WaterwayAreaImport) },
		Handle: manualImport(imports.WAJobKind, importWaterwayArea),
		NoConn: true,
	})).Methods(http.MethodPost)

	api.Handle("/imports/waterwaygauge", waterwayAdmin(&JSONHandler{
		Input:  func() interface{} { return new(models.WaterwayGaugeImport) },
		Handle: manualImport(imports.WGJobKind, importWaterwayGauge),
		NoConn: true,
	})).Methods(http.MethodPost)

	api.Handle("/imports/distancemarksvirtual", waterwayAdmin(&JSONHandler{
		Input:  func() interface{} { return new(models.DistanceMarksVirtualImport) },
		Handle: manualImport(imports.DMVJobKind, importDistancemarksVirtual),
		NoConn: true,
	})).Methods(http.MethodPost)

	api.Handle("/imports/fairwaydimension", waterwayAdmin(&JSONHandler{
		Input:  func() interface{} { return new(models.FairwayDimensionImport) },
		Handle: manualImport(imports.FDJobKind, importFairwayDimension),
		NoConn: true,
	})).Methods(http.MethodPost)

	api.Handle("/imports/distancemarks", waterwayAdmin(&JSONHandler{
		Input:  func() interface{} { return new(models.DistanceMarksAshoreImport) },
		Handle: manualImport(imports.DMAJobKind, importDistanceMarksAshore),
		NoConn: true,
	})).Methods(http.MethodPost)

	api.Handle("/imports/stretch", sysAdmin(&JSONHandler{
		Input:  func() interface{} { return new(models.StretchImport) },
		Handle: manualImport(imports.STJobKind, importStretch),
		NoConn: true,
	})).Methods(http.MethodPost)

	// Import scheduler configuration
	api.Handle("/imports/config/{id:[0-9]+}/run",
		waterwayAdmin(&JSONHandler{
			Handle: runImportConfig,
		})).Methods(http.MethodGet)

	api.Handle("/imports/config/{id:[0-9]+}",
		waterwayAdmin(&JSONHandler{
			Input:  func() interface{} { return new(imports.Config) },
			Handle: modifyImportConfig,
		})).Methods(http.MethodPatch)

	api.Handle("/imports/config/{id:[0-9]+}",
		waterwayAdmin(&JSONHandler{
			Handle: deleteImportConfig,
		})).Methods(http.MethodDelete)

	api.Handle("/imports/config/{id:[0-9]+}",
		waterwayAdmin(&JSONHandler{
			Handle: infoImportConfig,
		})).Methods(http.MethodGet)

	api.Handle("/imports/config",
		waterwayAdmin(&JSONHandler{
			Input:  func() interface{} { return new(imports.Config) },
			Handle: addImportConfig,
		})).Methods(http.MethodPost)

	api.Handle("/imports/config",
		waterwayAdmin(&JSONHandler{
			Handle: listImportConfigs,
		})).Methods(http.MethodGet)

	// Import queue
	lsImports := waterwayAdmin(&JSONHandler{
		Handle: listImports,
	})

	api.Handle("/imports", lsImports).
		Methods(http.MethodGet)

	api.Handle("/imports/{id:[0-9]+}", waterwayAdmin(&JSONHandler{
		Handle: importLogs,
	})).Methods(http.MethodGet)

	api.Handle("/imports", waterwayAdmin(&JSONHandler{
		Input:  func() interface{} { return &[]models.Review{} },
		Handle: reviewImports,
	})).Methods(http.MethodPatch)

	api.Handle("/imports/{id:[0-9]+}", waterwayAdmin(&JSONHandler{
		Handle: deleteImport,
	})).Methods(http.MethodDelete)

	// Handler to review an import which is pending.
	api.Handle("/imports/{id:[0-9]+}/{state:(?:accepted|declined)}",
		waterwayAdmin(&JSONHandler{
			Handle: reviewImport,
		})).Methods(http.MethodPut)

	// 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)
}