From ff77fee00a6118e5458ff5b3544b3a0a227b5095 Mon Sep 17 00:00:00 2001 From: pomdtr Date: Mon, 28 Apr 2025 17:32:10 +0200 Subject: [PATCH] move back crons and private/public fields to the app config --- app/app.go | 13 +++++++--- cmd/crons.go | 18 +++++++++++--- cmd/up.go | 38 ++++++++++++++--------------- example/.smallweb/config.json | 1 - example/ls/smallweb.json | 5 +--- schemas/config.schema.json | 46 ----------------------------------- schemas/manifest.schema.json | 46 +++++++++++++++++++++++++++++++++++ 7 files changed, 89 insertions(+), 78 deletions(-) diff --git a/app/app.go b/app/app.go index bfa6051..7e254dd 100644 --- a/app/app.go +++ b/app/app.go @@ -20,13 +20,18 @@ var ( ) type AppConfig struct { - Entrypoint string `json:"entrypoint,omitempty"` - Root string `json:"root,omitempty"` + Entrypoint string `json:"entrypoint,omitempty"` + Root string `json:"root,omitempty"` + Crons []CronJob `json:"cron"` + Private bool `json:"private"` + PrivateRoutes []string `json:"privateRoutes"` + PublicRoutes []string `json:"publicRoutes"` } type CronJob struct { - Schedule string `json:"schedule"` - Args []string `json:"args"` + Description string `json:"description"` + Schedule string `json:"schedule"` + Args []string `json:"args"` } type App struct { diff --git a/cmd/crons.go b/cmd/crons.go index 23f4df2..802ac73 100644 --- a/cmd/crons.go +++ b/cmd/crons.go @@ -47,7 +47,12 @@ func NewCmdCrons() *cobra.Command { Short: "List cron jobs", RunE: func(cmd *cobra.Command, args []string) error { var crons []CronItem - for _, appname := range k.MapKeys("apps") { + apps, err := app.ListApps(k.String("dir")) + if err != nil { + return fmt.Errorf("failed to list apps: %w", err) + } + + for _, appname := range apps { if len(args) > 0 && appname != args[0] { continue } else if len(args) == 0 && !flags.all { @@ -69,11 +74,16 @@ func NewCmdCrons() *cobra.Command { } } - for _, job := range k.Slices(fmt.Sprintf("apps.%s.crons", appname)) { + a, err := app.LoadApp(appname, k.String("dir"), k.String("domain"), k.Bool(fmt.Sprintf("apps.%s.admin", appname))) + if err != nil { + return fmt.Errorf("failed to load app %s: %w", appname, err) + } + + for _, job := range a.Config.Crons { crons = append(crons, CronItem{ App: appname, - Args: job.Strings("args"), - Schedule: job.String("schedule"), + Args: job.Args, + Schedule: job.Schedule, }) } } diff --git a/cmd/up.go b/cmd/up.go index b71e359..35e060a 100644 --- a/cmd/up.go +++ b/cmd/up.go @@ -694,8 +694,21 @@ func (me *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { return } + wk, err := me.GetWorker(appname, k.String("dir"), k.String("domain")) + if err != nil { + if errors.Is(err, app.ErrAppNotFound) { + w.WriteHeader(http.StatusNotFound) + w.Write([]byte(fmt.Sprintf("No app found for host %s", r.Host))) + return + } + + w.WriteHeader(http.StatusInternalServerError) + fmt.Fprintf(w, "failed to get worker: %v", err) + return + } + claims, err := me.extractClaims(r) - if err != nil && isRoutePrivate(appname, r.URL.Path) { + if err != nil && isRoutePrivate(wk.App, r.URL.Path) { if me.oidcIssuerUrl == nil { http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized) return @@ -775,7 +788,7 @@ func (me *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { } } - if isRoutePrivate(appname, r.URL.Path) && !isAuthorized(appname, claims.Email, claims.Group) { + if isRoutePrivate(wk.App, r.URL.Path) && !isAuthorized(appname, claims.Email, claims.Group) { if claims.Email == "" { http.Redirect(w, r, fmt.Sprintf("https://%s/_smallweb/signin", r.Host), http.StatusTemporaryRedirect) return @@ -790,32 +803,19 @@ func (me *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { r.Header.Set("Remote-Group", claims.Group) r.Header.Set("Remote-Name", claims.Name) - wk, err := me.GetWorker(appname, k.String("dir"), k.String("domain")) - if err != nil { - if errors.Is(err, app.ErrAppNotFound) { - w.WriteHeader(http.StatusNotFound) - w.Write([]byte(fmt.Sprintf("No app found for host %s", r.Host))) - return - } - - w.WriteHeader(http.StatusInternalServerError) - fmt.Fprintf(w, "failed to get worker: %v", err) - return - } - wk.ServeHTTP(w, r) } -func isRoutePrivate(appname string, route string) bool { - isPrivate := k.Bool(fmt.Sprintf("apps.%s.private", appname)) +func isRoutePrivate(a app.App, route string) bool { + isPrivate := a.Config.Private - for _, publicRoute := range k.Strings(fmt.Sprintf("apps.%s.publicRoutes", appname)) { + for _, publicRoute := range a.Config.PublicRoutes { if ok, _ := doublestar.Match(publicRoute, route); ok { isPrivate = false } } - for _, privateRoute := range k.Strings(fmt.Sprintf("apps.%s.privateRoutes", appname)) { + for _, privateRoute := range a.Config.PrivateRoutes { if ok, _ := doublestar.Match(privateRoute, route); ok { isPrivate = true } diff --git a/example/.smallweb/config.json b/example/.smallweb/config.json index 45aebe3..950bf63 100644 --- a/example/.smallweb/config.json +++ b/example/.smallweb/config.json @@ -8,7 +8,6 @@ "apps": { "ls": { "admin": true, - "private": true, "additionalDomains": [ "custom-domain.localhost" ] diff --git a/example/ls/smallweb.json b/example/ls/smallweb.json index d40628a..e72dc54 100644 --- a/example/ls/smallweb.json +++ b/example/ls/smallweb.json @@ -1,6 +1,3 @@ { - "private": true, - "publicRoutes": [ - "/public/*" - ] + "private": true } diff --git a/schemas/config.schema.json b/schemas/config.schema.json index 10db2e5..d75145e 100644 --- a/schemas/config.schema.json +++ b/schemas/config.schema.json @@ -65,52 +65,6 @@ "description": "Give the app admin privileges", "type": "boolean" }, - "private": { - "description": "Protect all routes behind authentication", - "type": "boolean" - }, - "privateRoutes": { - "description": "Make specific routes private", - "type": "array", - "items": { - "type": "string" - } - }, - "publicRoutes": { - "description": "Make specific routes public", - "type": "array", - "items": { - "type": "string" - } - }, - "crons": { - "description": "Cron jobs", - "type": "array", - "items": { - "type": "object", - "required": [ - "schedule", - "args" - ], - "properties": { - "schedule": { - "description": "Cron schedule", - "type": "string" - }, - "description": { - "type": "string", - "description": "An optional description for the task" - }, - "args": { - "description": "Cron arguments", - "type": "array", - "items": { - "type": "string" - } - } - } - } - }, "additionalDomains": { "description": "Additional app domains", "type": "array", diff --git a/schemas/manifest.schema.json b/schemas/manifest.schema.json index bb0e3c4..14c972e 100644 --- a/schemas/manifest.schema.json +++ b/schemas/manifest.schema.json @@ -10,6 +10,52 @@ "description": "The root directory of the project", "type": "string" }, + "private": { + "description": "Protect all routes behind authentication", + "type": "boolean" + }, + "privateRoutes": { + "description": "Make specific routes private", + "type": "array", + "items": { + "type": "string" + } + }, + "publicRoutes": { + "description": "Make specific routes public", + "type": "array", + "items": { + "type": "string" + } + }, + "crons": { + "description": "Cron jobs", + "type": "array", + "items": { + "type": "object", + "required": [ + "schedule", + "args" + ], + "properties": { + "schedule": { + "description": "Cron schedule", + "type": "string" + }, + "description": { + "type": "string", + "description": "An optional description for the task" + }, + "args": { + "description": "Cron arguments", + "type": "array", + "items": { + "type": "string" + } + } + } + } + }, "labels": { "description": "Labels for the project", "type": "object", -- 2.51.2