4
0
Эх сурвалжийг харах

Make it possible to redirect to a login url unless authenticated (#347)

* feature: Try to navigate to UrlOnUnauthenticated if set and not authenticated

* refactor: use better naming

* feature: default to allow guest
Simon Dahlbacka 1 жил өмнө
parent
commit
35dca50863

+ 3 - 0
internal/config/config.go

@@ -130,6 +130,8 @@ type Config struct {
 	DefaultIconForActions           string
 	DefaultIconForDirectories       string
 	DefaultIconForBack              string
+	AuthLoginUrl                    string
+	AuthAllowGuest                  bool
 
 	usedConfigDir string
 }
@@ -177,6 +179,7 @@ func DefaultConfigWithBasePort(basePort int) *Config {
 	config.DefaultPermissions.Logs = true
 	config.AuthJwtClaimUsername = "name"
 	config.AuthJwtClaimUserGroup = "group"
+	config.AuthAllowGuest = true
 	config.WebUIDir = "./webui"
 	config.CronSupportForSeconds = false
 	config.SectionNavigationStyle = "sidebar"

+ 4 - 0
internal/grpcapi/grpcApi.go

@@ -269,6 +269,10 @@ func (api *oliveTinAPI) GetDashboardComponents(ctx ctx.Context, req *pb.GetDashb
 
 	res.AuthenticatedUser = user.Username
 
+	if res.AuthenticatedUser == "guest" && !cfg.AuthAllowGuest {
+		return nil, status.Errorf(codes.PermissionDenied, "Unauthenticated")
+	}
+
 	return res, nil
 }
 

+ 13 - 0
internal/httpservers/restapi.go

@@ -5,7 +5,9 @@ import (
 	"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
 	log "github.com/sirupsen/logrus"
 	"google.golang.org/grpc"
+	"google.golang.org/grpc/codes"
 	"google.golang.org/grpc/metadata"
+	"google.golang.org/grpc/status"
 	"google.golang.org/protobuf/encoding/protojson"
 	"net/http"
 
@@ -83,10 +85,21 @@ func startRestAPIServer(globalConfig *config.Config) error {
 	return http.ListenAndServe(cfg.ListenAddressRestActions, cors.AllowCors(mux))
 }
 
+func errorHandler(ctx context.Context, mux *runtime.ServeMux, marshaler runtime.Marshaler, w http.ResponseWriter, r *http.Request, err error) {
+	log.Errorf("Error handling request: %v", err)
+	md, ok := runtime.ServerMetadataFromContext(ctx)
+	if ok && md.HeaderMD.Get("username") == nil {
+		err = status.Error(codes.Unauthenticated, "unauthenticated request")
+	}
+
+	runtime.DefaultHTTPErrorHandler(ctx, mux, marshaler, w, r, err)
+}
+
 func newMux() *runtime.ServeMux {
 	// The MarshalOptions set some important compatibility settings for the webui. See below.
 	mux := runtime.NewServeMux(
 		runtime.WithMetadata(parseRequestMetadata),
+		runtime.WithErrorHandler(errorHandler),
 		runtime.WithMarshalerOption(runtime.MIMEWildcard, &runtime.HTTPBodyMarshaler{
 			Marshaler: &runtime.JSONPb{
 				MarshalOptions: protojson.MarshalOptions{

+ 2 - 0
internal/httpservers/webuiServer.go

@@ -32,6 +32,7 @@ type webUISettings struct {
 	SshFoundKey            string
 	SshFoundConfig         string
 	EnableCustomJs         bool
+	AuthLoginUrl           string
 }
 
 func findWebuiDir() string {
@@ -117,6 +118,7 @@ func generateWebUISettings(w http.ResponseWriter, r *http.Request) {
 		SshFoundKey:            installationinfo.Runtime.SshFoundKey,
 		SshFoundConfig:         installationinfo.Runtime.SshFoundConfig,
 		EnableCustomJs:         cfg.EnableCustomJs,
+		AuthLoginUrl:           cfg.AuthLoginUrl,
 	})
 
 	w.Header().Add("Content-Type", "application/json")

+ 3 - 0
webui.dev/main.js

@@ -58,6 +58,9 @@ function fetchGetDashboardComponents () {
   window.fetch(window.restBaseUrl + 'GetDashboardComponents', {
     cors: 'cors'
   }).then(res => {
+    if (!res.ok && res.status === 401) {
+      window.location.href = window.settings.AuthLoginUrl
+    }
     return res.json()
   }).then(res => {
     if (!window.restAvailable) {