Refactor server and templates package

This commit is contained in:
Tom Wiesing 2023-01-19 13:22:48 +01:00
parent b6bf0a8900
commit 6ede99d7c6
No known key found for this signature in database
105 changed files with 341 additions and 339 deletions

View file

@ -1 +1 @@
golang 1.19.2 golang 1.19.5

View file

@ -6,10 +6,10 @@ wdcli:
go generate ./internal/dis/component/control/static/ go generate ./internal/dis/component/control/static/
go build -o ./wdcli ./cmd/wdcli go build -o ./wdcli ./cmd/wdcli
deps: internal/dis/component/control/static/node_modules deps: internal/dis/component/server/assets/node_modules
internal/dis/component/control/static/node_modules: internal/dis/component/server/assets/node_modules:
cd internal/dis/component/control/static/ && yarn install cd internal/dis/component/server/assets/ && yarn install
clean: clean:
rm wdcli rm wdcli

View file

@ -3,7 +3,7 @@ package cmd
import ( import (
wisski_distillery "github.com/FAU-CDI/wisski-distillery" wisski_distillery "github.com/FAU-CDI/wisski-distillery"
"github.com/FAU-CDI/wisski-distillery/internal/cli" "github.com/FAU-CDI/wisski-distillery/internal/cli"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/control/static" "github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/assets"
) )
// License is the 'wdcli license' command. // License is the 'wdcli license' command.
@ -28,7 +28,7 @@ func (license) AfterParse() error {
} }
func (license) Run(context wisski_distillery.Context) error { func (license) Run(context wisski_distillery.Context) error {
context.Printf(stringLicenseInfo, wisski_distillery.License, cli.LegalNotices, static.AssetsDisclaimer) context.Printf(stringLicenseInfo, wisski_distillery.License, cli.LegalNotices, assets.Disclaimer)
return nil return nil
} }

View file

@ -72,7 +72,7 @@ func (si systemupdate) Run(context wisski_distillery.Context) error {
dis.Instances().Path(), dis.Instances().Path(),
dis.Exporter().StagingPath(), dis.Exporter().StagingPath(),
dis.Exporter().ArchivePath(), dis.Exporter().ArchivePath(),
dis.Custom().CustomAssetsPath(), dis.Templating().CustomAssetsPath(),
} { } {
context.Println(d) context.Println(d)
if err := dis.Still.Environment.MkdirAll(d, environment.DefaultDirPerm); err != nil { if err := dis.Still.Environment.MkdirAll(d, environment.DefaultDirPerm); err != nil {

View file

@ -1,7 +1,7 @@
package cli package cli
// =========================================================================================================== // ===========================================================================================================
// This file was generated automatically at 16-01-2023 17:01:43 using gogenlicense. // This file was generated automatically at 19-01-2023 12:17:46 using gogenlicense.
// Do not edit manually, as changes may be overwritten. // Do not edit manually, as changes may be overwritten.
// =========================================================================================================== // ===========================================================================================================
@ -2417,7 +2417,7 @@ package cli
// # Generation // # Generation
// //
// This variable and the associated documentation have been automatically generated using the 'gogenlicense' tool. // This variable and the associated documentation have been automatically generated using the 'gogenlicense' tool.
// It was last updated at 16-01-2023 17:01:43. // It was last updated at 19-01-2023 12:17:46.
var LegalNotices string var LegalNotices string
func init() { func init() {

View file

@ -5,7 +5,7 @@ import (
"net/http" "net/http"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component" "github.com/FAU-CDI/wisski-distillery/internal/dis/component"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/control/static/custom" "github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/templates"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/sql" "github.com/FAU-CDI/wisski-distillery/internal/dis/component/sql"
"github.com/FAU-CDI/wisski-distillery/pkg/lazy" "github.com/FAU-CDI/wisski-distillery/pkg/lazy"
"github.com/gorilla/sessions" "github.com/gorilla/sessions"
@ -17,7 +17,7 @@ type Auth struct {
Dependencies struct { Dependencies struct {
SQL *sql.SQL SQL *sql.SQL
UserDeleteHooks []component.UserDeleteHook UserDeleteHooks []component.UserDeleteHook
Custom *custom.Custom Templating *templates.Templating
} }
store lazy.Lazy[sessions.Store] store lazy.Lazy[sessions.Store]

View file

@ -8,8 +8,8 @@ import (
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/auth" "github.com/FAU-CDI/wisski-distillery/internal/dis/component/auth"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/auth/next" "github.com/FAU-CDI/wisski-distillery/internal/dis/component/auth/next"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/auth/policy" "github.com/FAU-CDI/wisski-distillery/internal/dis/component/auth/policy"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/control/static/custom"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/instances" "github.com/FAU-CDI/wisski-distillery/internal/dis/component/instances"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/templates"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/ssh2/sshkeys" "github.com/FAU-CDI/wisski-distillery/internal/dis/component/ssh2/sshkeys"
"github.com/FAU-CDI/wisski-distillery/internal/models" "github.com/FAU-CDI/wisski-distillery/internal/models"
"github.com/FAU-CDI/wisski-distillery/pkg/httpx" "github.com/FAU-CDI/wisski-distillery/pkg/httpx"
@ -20,7 +20,7 @@ type UserPanel struct {
component.Base component.Base
Dependencies struct { Dependencies struct {
Auth *auth.Auth Auth *auth.Auth
Custom *custom.Custom Templating *templates.Templating
Policy *policy.Policy Policy *policy.Policy
Instances *instances.Instances Instances *instances.Instances
Next *next.Next Next *next.Next
@ -106,14 +106,14 @@ func (panel *UserPanel) HandleRoute(ctx context.Context, route string) (http.Han
} }
type userFormContext struct { type userFormContext struct {
custom.BaseContext templates.BaseContext
httpx.FormContext httpx.FormContext
User *models.User User *models.User
} }
func (panel *UserPanel) UserFormContext2(tpl *custom.Template[userFormContext], last component.MenuItem, gaps ...custom.BaseContextGaps) func(ctx httpx.FormContext, r *http.Request) any { func (panel *UserPanel) UserFormContext2(tpl *templates.Template[userFormContext], last component.MenuItem, gaps ...templates.BaseContextGaps) func(ctx httpx.FormContext, r *http.Request) any {
var g custom.BaseContextGaps var g templates.BaseContextGaps
if len(gaps) > 1 { if len(gaps) > 1 {
panic("UserFormContext2: gaps must be of length 0 or 1") panic("UserFormContext2: gaps must be of length 0 or 1")
} }
@ -125,7 +125,7 @@ func (panel *UserPanel) UserFormContext2(tpl *custom.Template[userFormContext],
last, last,
} }
return custom.MappedHandler(tpl, func(ctx httpx.FormContext, r *http.Request) (userFormContext, custom.BaseContextGaps) { return templates.MappedHandler(tpl, func(ctx httpx.FormContext, r *http.Request) (userFormContext, templates.BaseContextGaps) {
uctx := userFormContext{FormContext: ctx} uctx := userFormContext{FormContext: ctx}
if user, err := panel.Dependencies.Auth.UserOf(r); err == nil { if user, err := panel.Dependencies.Auth.UserOf(r); err == nil {
uctx.User = &user.User uctx.User = &user.User

View file

@ -8,15 +8,15 @@ import (
_ "embed" _ "embed"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component" "github.com/FAU-CDI/wisski-distillery/internal/dis/component"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/control/static" "github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/assets"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/control/static/custom" templating "github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/templates"
"github.com/FAU-CDI/wisski-distillery/pkg/httpx" "github.com/FAU-CDI/wisski-distillery/pkg/httpx"
"github.com/FAU-CDI/wisski-distillery/pkg/httpx/field" "github.com/FAU-CDI/wisski-distillery/pkg/httpx/field"
) )
//go:embed "templates/password.html" //go:embed "templates/password.html"
var passwordHTML []byte var passwordHTML []byte
var passwordTemplate = custom.Parse[userFormContext]("password.html", passwordHTML, static.AssetsUser) var passwordTemplate = templating.Parse[userFormContext]("password.html", passwordHTML, assets.AssetsUser)
var ( var (
errPasswordsNotIdentical = errors.New("passwords are not identical") errPasswordsNotIdentical = errors.New("passwords are not identical")
@ -28,7 +28,7 @@ var (
) )
func (panel *UserPanel) routePassword(ctx context.Context) http.Handler { func (panel *UserPanel) routePassword(ctx context.Context) http.Handler {
tpl := passwordTemplate.Prepare(panel.Dependencies.Custom) tpl := passwordTemplate.Prepare(panel.Dependencies.Templating)
return &httpx.Form[struct{}]{ return &httpx.Form[struct{}]{
Fields: []field.Field{ Fields: []field.Field{

View file

@ -7,8 +7,8 @@ import (
"github.com/FAU-CDI/wisski-distillery/internal/dis/component" "github.com/FAU-CDI/wisski-distillery/internal/dis/component"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/auth" "github.com/FAU-CDI/wisski-distillery/internal/dis/component/auth"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/control/static" "github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/assets"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/control/static/custom" "github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/templates"
"github.com/FAU-CDI/wisski-distillery/internal/models" "github.com/FAU-CDI/wisski-distillery/internal/models"
"github.com/FAU-CDI/wisski-distillery/pkg/httpx" "github.com/FAU-CDI/wisski-distillery/pkg/httpx"
"github.com/FAU-CDI/wisski-distillery/pkg/httpx/field" "github.com/FAU-CDI/wisski-distillery/pkg/httpx/field"
@ -22,10 +22,10 @@ import (
//go:embed "templates/ssh.html" //go:embed "templates/ssh.html"
var sshHTML []byte var sshHTML []byte
var sshTemplate = custom.Parse[SSHTemplateContext]("ssh.html", sshHTML, static.AssetsUser) var sshTemplate = templates.Parse[SSHTemplateContext]("ssh.html", sshHTML, assets.AssetsUser)
type SSHTemplateContext struct { type SSHTemplateContext struct {
custom.BaseContext templates.BaseContext
Keys []models.Keys Keys []models.Keys
@ -37,7 +37,7 @@ type SSHTemplateContext struct {
} }
func (panel *UserPanel) sshRoute(ctx context.Context) http.Handler { func (panel *UserPanel) sshRoute(ctx context.Context) http.Handler {
tpl := sshTemplate.Prepare(panel.Dependencies.Custom, custom.BaseContextGaps{ tpl := sshTemplate.Prepare(panel.Dependencies.Templating, templates.BaseContextGaps{
Crumbs: []component.MenuItem{ Crumbs: []component.MenuItem{
{Title: "User", Path: "/user/"}, {Title: "User", Path: "/user/"},
{Title: "SSH Keys", Path: "/user/ssh/"}, {Title: "SSH Keys", Path: "/user/ssh/"},
@ -114,7 +114,7 @@ func (panel *UserPanel) sshDeleteRoute(ctx context.Context) http.Handler {
//go:embed "templates/ssh_add.html" //go:embed "templates/ssh_add.html"
var sshAddHTML []byte var sshAddHTML []byte
var sshAddTemplate = custom.ParseForm("ssh_add.html", sshAddHTML, static.AssetsUser) var sshAddTemplate = templates.ParseForm("ssh_add.html", sshAddHTML, assets.AssetsUser)
type addKeyResult struct { type addKeyResult struct {
User *auth.AuthUser User *auth.AuthUser
@ -123,7 +123,7 @@ type addKeyResult struct {
} }
func (panel *UserPanel) sshAddRoute(ctx context.Context) http.Handler { func (panel *UserPanel) sshAddRoute(ctx context.Context) http.Handler {
tpl := sshAddTemplate.Prepare(panel.Dependencies.Custom, custom.BaseContextGaps{ tpl := sshAddTemplate.Prepare(panel.Dependencies.Templating, templates.BaseContextGaps{
Crumbs: []component.MenuItem{ Crumbs: []component.MenuItem{
{Title: "User", Path: "/user/"}, {Title: "User", Path: "/user/"},
{Title: "SSH Keys", Path: "/user/ssh/"}, {Title: "SSH Keys", Path: "/user/ssh/"},
@ -139,7 +139,7 @@ func (panel *UserPanel) sshAddRoute(ctx context.Context) http.Handler {
FieldTemplate: field.PureCSSFieldTemplate, FieldTemplate: field.PureCSSFieldTemplate,
RenderTemplate: tpl.Template(), RenderTemplate: tpl.Template(),
RenderTemplateContext: custom.FormTemplateContext(tpl), RenderTemplateContext: templates.FormTemplateContext(tpl),
Validate: func(r *http.Request, values map[string]string) (ak addKeyResult, err error) { Validate: func(r *http.Request, values map[string]string) (ak addKeyResult, err error) {
ak.User, err = panel.Dependencies.Auth.UserOf(r) ak.User, err = panel.Dependencies.Auth.UserOf(r)

View file

@ -7,8 +7,8 @@ import (
"github.com/FAU-CDI/wisski-distillery/internal/dis/component" "github.com/FAU-CDI/wisski-distillery/internal/dis/component"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/auth" "github.com/FAU-CDI/wisski-distillery/internal/dis/component/auth"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/control/static" "github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/assets"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/control/static/custom" "github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/templates"
"github.com/FAU-CDI/wisski-distillery/pkg/httpx" "github.com/FAU-CDI/wisski-distillery/pkg/httpx"
"github.com/FAU-CDI/wisski-distillery/pkg/httpx/field" "github.com/FAU-CDI/wisski-distillery/pkg/httpx/field"
@ -17,10 +17,10 @@ import (
//go:embed "templates/totp_enable.html" //go:embed "templates/totp_enable.html"
var totpEnableHTML []byte var totpEnableHTML []byte
var totpEnable = custom.Parse[userFormContext]("totp_enable.html", totpEnableHTML, static.AssetsUser) var totpEnable = templates.Parse[userFormContext]("totp_enable.html", totpEnableHTML, assets.AssetsUser)
func (panel *UserPanel) routeTOTPEnable(ctx context.Context) http.Handler { func (panel *UserPanel) routeTOTPEnable(ctx context.Context) http.Handler {
tpl := totpEnable.Prepare(panel.Dependencies.Custom) tpl := totpEnable.Prepare(panel.Dependencies.Templating)
return &httpx.Form[struct{}]{ return &httpx.Form[struct{}]{
Fields: []field.Field{ Fields: []field.Field{
@ -69,7 +69,7 @@ func (panel *UserPanel) routeTOTPEnable(ctx context.Context) http.Handler {
//go:embed "templates/totp_enroll.html" //go:embed "templates/totp_enroll.html"
var totpEnrollHTML []byte var totpEnrollHTML []byte
var totpEnrollTemplate = custom.Parse[totpEnrollContext]("totp_enroll.html", totpEnrollHTML, static.AssetsUser) var totpEnrollTemplate = templates.Parse[totpEnrollContext]("totp_enroll.html", totpEnrollHTML, assets.AssetsUser)
type totpEnrollContext struct { type totpEnrollContext struct {
userFormContext userFormContext
@ -80,7 +80,7 @@ type totpEnrollContext struct {
} }
func (panel *UserPanel) routeTOTPEnroll(ctx context.Context) http.Handler { func (panel *UserPanel) routeTOTPEnroll(ctx context.Context) http.Handler {
tpl := totpEnrollTemplate.Prepare(panel.Dependencies.Custom, custom.BaseContextGaps{ tpl := totpEnrollTemplate.Prepare(panel.Dependencies.Templating, templates.BaseContextGaps{
Crumbs: []component.MenuItem{ Crumbs: []component.MenuItem{
{Title: "User", Path: "/user/"}, {Title: "User", Path: "/user/"},
{Title: "Enable TOTP", Path: "/user/totp/enable/"}, {Title: "Enable TOTP", Path: "/user/totp/enable/"},
@ -156,10 +156,10 @@ func (panel *UserPanel) routeTOTPEnroll(ctx context.Context) http.Handler {
//go:embed "templates/totp_disable.html" //go:embed "templates/totp_disable.html"
var totpDisableHTML []byte var totpDisableHTML []byte
var totpDisableTemplate = custom.Parse[userFormContext]("totp_disable.html", totpDisableHTML, static.AssetsUser) var totpDisableTemplate = templates.Parse[userFormContext]("totp_disable.html", totpDisableHTML, assets.AssetsUser)
func (panel *UserPanel) routeTOTPDisable(ctx context.Context) http.Handler { func (panel *UserPanel) routeTOTPDisable(ctx context.Context) http.Handler {
tpl := totpDisableTemplate.Prepare(panel.Dependencies.Custom) tpl := totpDisableTemplate.Prepare(panel.Dependencies.Templating)
return &httpx.Form[struct{}]{ return &httpx.Form[struct{}]{
Fields: []field.Field{ Fields: []field.Field{

View file

@ -9,17 +9,17 @@ import (
"github.com/FAU-CDI/wisski-distillery/internal/dis/component" "github.com/FAU-CDI/wisski-distillery/internal/dis/component"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/auth" "github.com/FAU-CDI/wisski-distillery/internal/dis/component/auth"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/control/static" "github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/assets"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/control/static/custom" "github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/templates"
"github.com/FAU-CDI/wisski-distillery/internal/models" "github.com/FAU-CDI/wisski-distillery/internal/models"
) )
//go:embed "templates/user.html" //go:embed "templates/user.html"
var userHTML []byte var userHTML []byte
var userTemplate = custom.Parse[userContext]("user.html", userHTML, static.AssetsUser) var userTemplate = templates.Parse[userContext]("user.html", userHTML, assets.AssetsUser)
type userContext struct { type userContext struct {
custom.BaseContext templates.BaseContext
*auth.AuthUser *auth.AuthUser
Grants []GrantWithURL Grants []GrantWithURL
@ -31,7 +31,7 @@ type GrantWithURL struct {
} }
func (panel *UserPanel) routeUser(ctx context.Context) http.Handler { func (panel *UserPanel) routeUser(ctx context.Context) http.Handler {
tpl := userTemplate.Prepare(panel.Dependencies.Custom, custom.BaseContextGaps{ tpl := userTemplate.Prepare(panel.Dependencies.Templating, templates.BaseContextGaps{
Crumbs: []component.MenuItem{ Crumbs: []component.MenuItem{
{Title: "User", Path: "/user/"}, {Title: "User", Path: "/user/"},
}, },
@ -42,7 +42,7 @@ func (panel *UserPanel) routeUser(ctx context.Context) http.Handler {
}, },
}) })
return tpl.HTMLHandlerWithGaps(func(r *http.Request, gaps *custom.BaseContextGaps) (uc userContext, err error) { return tpl.HTMLHandlerWithGaps(func(r *http.Request, gaps *templates.BaseContextGaps) (uc userContext, err error) {
// find the user // find the user
uc.AuthUser, err = panel.Dependencies.Auth.UserOf(r) uc.AuthUser, err = panel.Dependencies.Auth.UserOf(r)
if err != nil || uc.AuthUser == nil { if err != nil || uc.AuthUser == nil {

View file

@ -7,9 +7,9 @@ import (
"net/http" "net/http"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component" "github.com/FAU-CDI/wisski-distillery/internal/dis/component"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/control" "github.com/FAU-CDI/wisski-distillery/internal/dis/component/server"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/control/static" "github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/assets"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/control/static/custom" "github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/templates"
"github.com/FAU-CDI/wisski-distillery/pkg/httpx" "github.com/FAU-CDI/wisski-distillery/pkg/httpx"
"github.com/FAU-CDI/wisski-distillery/pkg/httpx/field" "github.com/FAU-CDI/wisski-distillery/pkg/httpx/field"
"github.com/gorilla/sessions" "github.com/gorilla/sessions"
@ -35,7 +35,7 @@ func (auth *Auth) UserOf(r *http.Request) (user *AuthUser, err error) {
} }
// try to read the name from the session // try to read the name from the session
name, ok := sess.Values[control.SessionUserKey] name, ok := sess.Values[server.SessionUserKey]
if !ok { if !ok {
return nil, nil return nil, nil
} }
@ -67,7 +67,7 @@ func (auth *Auth) UserOf(r *http.Request) (user *AuthUser, err error) {
func (auth *Auth) session(r *http.Request) (*sessions.Session, error) { func (auth *Auth) session(r *http.Request) (*sessions.Session, error) {
return auth.store.Get(func() sessions.Store { return auth.store.Get(func() sessions.Store {
return sessions.NewCookieStore([]byte(auth.Config.SessionSecret)) return sessions.NewCookieStore([]byte(auth.Config.SessionSecret))
}).Get(r, control.SessionCookie) }).Get(r, server.SessionCookie)
} }
func (auth *Auth) Menu(r *http.Request) []component.MenuItem { func (auth *Auth) Menu(r *http.Request) []component.MenuItem {
@ -101,7 +101,7 @@ func (auth *Auth) Login(w http.ResponseWriter, r *http.Request, user *AuthUser)
if err != nil { if err != nil {
return err return err
} }
sess.Values[control.SessionUserKey] = user.User.User sess.Values[server.SessionUserKey] = user.User.User
return sess.Save(r, w) return sess.Save(r, w)
} }
@ -120,7 +120,7 @@ func (auth *Auth) Logout(w http.ResponseWriter, r *http.Request) error {
//go:embed "login.html" //go:embed "login.html"
var loginHTML []byte var loginHTML []byte
var loginTemplate = custom.ParseForm("login.html", loginHTML, static.AssetsUser) var loginTemplate = templates.ParseForm("login.html", loginHTML, assets.AssetsUser)
var loginResponse = httpx.Response{ var loginResponse = httpx.Response{
ContentType: "text/plain", ContentType: "text/plain",
@ -131,7 +131,7 @@ var errLoginFailed = errors.New("Login failed")
// authLogin implements a view to login a user // authLogin implements a view to login a user
func (auth *Auth) authLogin(ctx context.Context) http.Handler { func (auth *Auth) authLogin(ctx context.Context) http.Handler {
tpl := loginTemplate.Prepare(auth.Dependencies.Custom) tpl := loginTemplate.Prepare(auth.Dependencies.Templating)
return &httpx.Form[*AuthUser]{ return &httpx.Form[*AuthUser]{
Fields: []field.Field{ Fields: []field.Field{
@ -145,7 +145,7 @@ func (auth *Auth) authLogin(ctx context.Context) http.Handler {
if context.Err != nil { if context.Err != nil {
context.Err = errLoginFailed context.Err = errLoginFailed
} }
tpl.Execute(w, r, custom.BaseFormContext{FormContext: context}, custom.BaseContextGaps{ tpl.Execute(w, r, templates.BaseFormContext{FormContext: context}, templates.BaseContextGaps{
Crumbs: []component.MenuItem{ Crumbs: []component.MenuItem{
{Title: "Login", Path: template.URL(r.URL.RequestURI())}, {Title: "Login", Path: template.URL(r.URL.RequestURI())},
}, },

View file

@ -1,71 +0,0 @@
package control
import (
"context"
"embed"
"io"
"path/filepath"
"syscall"
"github.com/FAU-CDI/wisski-distillery/internal/bootstrap"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/control/static/custom"
"github.com/FAU-CDI/wisski-distillery/pkg/environment"
)
// Control represents the running control server.
type Control struct {
component.Base
Dependencies struct {
Routeables []component.Routeable
Cronables []component.Cronable
Custom *custom.Custom
}
}
var (
_ component.Installable = (*Control)(nil)
)
func (control Control) Path() string {
return filepath.Join(control.Still.Config.DeployRoot, "core", "dis")
}
//go:embed all:control control.env
var resources embed.FS
func (control *Control) Stack(env environment.Environment) component.StackWithResources {
return component.MakeStack(control, env, component.StackWithResources{
Resources: resources,
ContextPath: "control",
EnvPath: "control.env",
EnvContext: map[string]string{
"DOCKER_NETWORK_NAME": control.Config.DockerNetworkName,
"HOST_RULE": control.Config.DefaultHostRule(),
"HTTPS_ENABLED": control.Config.HTTPSEnabledEnv(),
"CONFIG_PATH": control.Config.ConfigPath,
"DEPLOY_ROOT": control.Config.DeployRoot,
"SELF_OVERRIDES_FILE": control.Config.SelfOverridesFile,
"SELF_RESOLVER_BLOCK_FILE": control.Config.SelfResolverBlockFile,
"CUSTOM_ASSETS_PATH": control.Dependencies.Custom.CustomAssetsPath(),
},
CopyContextFiles: []string{bootstrap.Executable},
})
}
// Trigger triggers the active cron run to immediatly invoke cron.
func (control *Control) Trigger(ctx context.Context, env environment.Environment) error {
return control.Stack(env).Kill(ctx, io.Discard, "control", syscall.SIGHUP)
}
func (control Control) Context(parent component.InstallationContext) component.InstallationContext {
return component.InstallationContext{
bootstrap.Executable: control.Config.CurrentExecutable(control.Environment), // TODO: Does this make sense?
}
}

View file

@ -1,26 +0,0 @@
package static
import _ "embed"
// This file was automatically generated. Do not edit.
//go:embed "assets_disclaimer.txt"
var AssetsDisclaimer string
// AssetsDefault contains assets for the 'Default' entrypoint.
var AssetsDefault = Assets{
Scripts: `<script type="module" src="/static/Default.38d394c2.js"></script><script src="/static/Default.38d394c2.js" nomodule="" defer></script><script type="module" src="/static/Default.38d394c2.js"></script><script src="/static/Default.38d394c2.js" nomodule="" defer></script>`,
Styles: `<link rel="stylesheet" href="/static/Default.db26a303.css"><link rel="stylesheet" href="/static/Default.f9675eae.css">`,
}
// AssetsUser contains assets for the 'User' entrypoint.
var AssetsUser = Assets{
Scripts: `<script type="module" src="/static/Default.38d394c2.js"></script><script src="/static/Default.38d394c2.js" nomodule="" defer></script><script type="module" src="/static/User.e0367d79.js"></script><script src="/static/User.b2f9a57c.js" nomodule="" defer></script>`,
Styles: `<link rel="stylesheet" href="/static/Default.db26a303.css"><link rel="stylesheet" href="/static/User.68febbf8.css"><link rel="stylesheet" href="/static/User.840de3b4.css">`,
}
// AssetsAdmin contains assets for the 'Admin' entrypoint.
var AssetsAdmin = Assets{
Scripts: `<script nomodule="" defer src="/static/User.b2f9a57c.js"></script><script type="module" src="/static/User.e0367d79.js"></script><script type="module" src="/static/Default.38d394c2.js"></script><script src="/static/Default.38d394c2.js" nomodule="" defer></script><script type="module" src="/static/Admin.1a380f6f.js"></script><script src="/static/Admin.cb58d290.js" nomodule="" defer></script>`,
Styles: `<link rel="stylesheet" href="/static/Default.db26a303.css"><link rel="stylesheet" href="/static/Admin.6d59e220.css"><link rel="stylesheet" href="/static/User.840de3b4.css"><link rel="stylesheet" href="/static/User.68febbf8.css"><link rel="stylesheet" href="/static/Admin.6d2ae968.css">`,
}

View file

@ -1,22 +0,0 @@
package custom
import (
"path/filepath"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
)
// CustomAssetsPath is the path custom assets are stored at
func (custom *Custom) CustomAssetsPath() string {
return filepath.Join(custom.Config.DeployRoot, "core", "assets")
}
func (custom *Custom) CustomAssetPath(name string) string {
return filepath.Join(custom.CustomAssetsPath(), name)
}
func (custom *Custom) BackupName() string { return "custom" }
func (custom *Custom) Backup(context component.StagingContext) error {
return context.CopyDirectory("", custom.CustomAssetsPath())
}

View file

@ -11,9 +11,9 @@ import (
"github.com/FAU-CDI/wdresolve/resolvers" "github.com/FAU-CDI/wdresolve/resolvers"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component" "github.com/FAU-CDI/wisski-distillery/internal/dis/component"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/auth" "github.com/FAU-CDI/wisski-distillery/internal/dis/component/auth"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/control/static"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/control/static/custom"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/instances" "github.com/FAU-CDI/wisski-distillery/internal/dis/component/instances"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/assets"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/templates"
"github.com/FAU-CDI/wisski-distillery/pkg/lazy" "github.com/FAU-CDI/wisski-distillery/pkg/lazy"
"github.com/rs/zerolog" "github.com/rs/zerolog"
@ -24,7 +24,7 @@ type Resolver struct {
component.Base component.Base
Dependencies struct { Dependencies struct {
Instances *instances.Instances Instances *instances.Instances
Custom *custom.Custom Templating *templates.Templating
Auth *auth.Auth Auth *auth.Auth
} }
@ -50,15 +50,15 @@ func (resolver *Resolver) Routes() component.Routes {
//go:embed "resolver.html" //go:embed "resolver.html"
var resolverHTML []byte var resolverHTML []byte
var resolverTemplate = custom.Parse[resolverContext]("resolver.html", resolverHTML, static.AssetsDefault) var resolverTemplate = templates.Parse[resolverContext]("resolver.html", resolverHTML, assets.AssetsDefault)
type resolverContext struct { type resolverContext struct {
custom.BaseContext templates.BaseContext
wdresolve.IndexContext wdresolve.IndexContext
} }
func (resolver *Resolver) HandleRoute(ctx context.Context, route string) (http.Handler, error) { func (resolver *Resolver) HandleRoute(ctx context.Context, route string) (http.Handler, error) {
tpl := resolverTemplate.Prepare(resolver.Dependencies.Custom, custom.BaseContextGaps{ tpl := resolverTemplate.Prepare(resolver.Dependencies.Templating, templates.BaseContextGaps{
Crumbs: []component.MenuItem{ Crumbs: []component.MenuItem{
{Title: "Resolver", Path: "/wisski/get/"}, {Title: "Resolver", Path: "/wisski/get/"},
}, },

View file

@ -7,10 +7,10 @@ import (
"github.com/FAU-CDI/wisski-distillery/internal/dis/component" "github.com/FAU-CDI/wisski-distillery/internal/dis/component"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/auth" "github.com/FAU-CDI/wisski-distillery/internal/dis/component/auth"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/auth/policy" "github.com/FAU-CDI/wisski-distillery/internal/dis/component/auth/policy"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/control/static/custom"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/exporter" "github.com/FAU-CDI/wisski-distillery/internal/dis/component/exporter"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/exporter/logger" "github.com/FAU-CDI/wisski-distillery/internal/dis/component/exporter/logger"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/instances/purger" "github.com/FAU-CDI/wisski-distillery/internal/dis/component/instances/purger"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/templates"
"github.com/julienschmidt/httprouter" "github.com/julienschmidt/httprouter"
"github.com/rs/zerolog" "github.com/rs/zerolog"
@ -32,7 +32,7 @@ type Admin struct {
Policy *policy.Policy Policy *policy.Policy
Custom *custom.Custom Templating *templates.Templating
Purger *purger.Purger Purger *purger.Purger
} }

View file

@ -8,9 +8,9 @@ import (
_ "embed" _ "embed"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component" "github.com/FAU-CDI/wisski-distillery/internal/dis/component"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/control/static"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/control/static/custom"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/instances" "github.com/FAU-CDI/wisski-distillery/internal/dis/component/instances"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/assets"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/templates"
"github.com/FAU-CDI/wisski-distillery/internal/models" "github.com/FAU-CDI/wisski-distillery/internal/models"
"github.com/FAU-CDI/wisski-distillery/pkg/httpx" "github.com/FAU-CDI/wisski-distillery/pkg/httpx"
"github.com/FAU-CDI/wisski-distillery/pkg/lazy" "github.com/FAU-CDI/wisski-distillery/pkg/lazy"
@ -19,16 +19,16 @@ import (
//go:embed "html/components.html" //go:embed "html/components.html"
var componentsHTML []byte var componentsHTML []byte
var componentsTemplate = custom.Parse[componentContext]("components.html", componentsHTML, static.AssetsAdmin) var componentsTemplate = templates.Parse[componentContext]("components.html", componentsHTML, assets.AssetsAdmin)
type componentContext struct { type componentContext struct {
custom.BaseContext templates.BaseContext
Analytics lazy.PoolAnalytics Analytics lazy.PoolAnalytics
} }
func (admin *Admin) components(ctx context.Context) http.Handler { func (admin *Admin) components(ctx context.Context) http.Handler {
tpl := componentsTemplate.Prepare(admin.Dependencies.Custom, custom.BaseContextGaps{ tpl := componentsTemplate.Prepare(admin.Dependencies.Templating, templates.BaseContextGaps{
Crumbs: []component.MenuItem{ Crumbs: []component.MenuItem{
{Title: "Admin", Path: "/admin/"}, {Title: "Admin", Path: "/admin/"},
{Title: "Components", Path: "/admin/components/"}, {Title: "Components", Path: "/admin/components/"},
@ -43,17 +43,17 @@ func (admin *Admin) components(ctx context.Context) http.Handler {
//go:embed "html/ingredients.html" //go:embed "html/ingredients.html"
var ingredientsHTML []byte var ingredientsHTML []byte
var ingredientsTemplate = custom.Parse[ingredientsContext]("ingredients.html", ingredientsHTML, static.AssetsAdmin) var ingredientsTemplate = templates.Parse[ingredientsContext]("ingredients.html", ingredientsHTML, assets.AssetsAdmin)
type ingredientsContext struct { type ingredientsContext struct {
custom.BaseContext templates.BaseContext
Instance models.Instance Instance models.Instance
Analytics *lazy.PoolAnalytics Analytics *lazy.PoolAnalytics
} }
func (admin *Admin) ingredients(ctx context.Context) http.Handler { func (admin *Admin) ingredients(ctx context.Context) http.Handler {
tpl := ingredientsTemplate.Prepare(admin.Dependencies.Custom, custom.BaseContextGaps{ tpl := ingredientsTemplate.Prepare(admin.Dependencies.Templating, templates.BaseContextGaps{
Crumbs: []component.MenuItem{ Crumbs: []component.MenuItem{
{Title: "Admin", Path: "/admin/"}, {Title: "Admin", Path: "/admin/"},
{Title: "Instance", Path: "* to be updated *"}, {Title: "Instance", Path: "* to be updated *"},
@ -61,7 +61,7 @@ func (admin *Admin) ingredients(ctx context.Context) http.Handler {
}, },
}) })
return tpl.HTMLHandlerWithGaps(func(r *http.Request, gaps *custom.BaseContextGaps) (ic ingredientsContext, err error) { return tpl.HTMLHandlerWithGaps(func(r *http.Request, gaps *templates.BaseContextGaps) (ic ingredientsContext, err error) {
slug := httprouter.ParamsFromContext(r.Context()).ByName("slug") slug := httprouter.ParamsFromContext(r.Context()).ByName("slug")
gaps.Crumbs[1] = component.MenuItem{Title: "Instance", Path: template.URL("/admin/instance/" + slug)} gaps.Crumbs[1] = component.MenuItem{Title: "Instance", Path: template.URL("/admin/instance/" + slug)}

View file

@ -8,9 +8,9 @@ import (
"net/http" "net/http"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component" "github.com/FAU-CDI/wisski-distillery/internal/dis/component"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/control/static"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/control/static/custom"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/instances" "github.com/FAU-CDI/wisski-distillery/internal/dis/component/instances"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/assets"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/templates"
"github.com/FAU-CDI/wisski-distillery/internal/models" "github.com/FAU-CDI/wisski-distillery/internal/models"
"github.com/FAU-CDI/wisski-distillery/internal/wisski" "github.com/FAU-CDI/wisski-distillery/internal/wisski"
"github.com/FAU-CDI/wisski-distillery/pkg/httpx" "github.com/FAU-CDI/wisski-distillery/pkg/httpx"
@ -22,10 +22,10 @@ import (
//go:embed "html/grants.html" //go:embed "html/grants.html"
var grantsHTML []byte var grantsHTML []byte
var grantsTemplate = custom.Parse[grantsContext]("grants.html", grantsHTML, static.AssetsAdmin) var grantsTemplate = templates.Parse[grantsContext]("grants.html", grantsHTML, assets.AssetsAdmin)
type grantsContext struct { type grantsContext struct {
custom.BaseContext templates.BaseContext
Error string Error string
@ -38,7 +38,7 @@ type grantsContext struct {
} }
func (admin *Admin) grants(ctx context.Context) http.Handler { func (admin *Admin) grants(ctx context.Context) http.Handler {
tpl := grantsTemplate.Prepare(admin.Dependencies.Custom, custom.BaseContextGaps{ tpl := grantsTemplate.Prepare(admin.Dependencies.Templating, templates.BaseContextGaps{
Crumbs: []component.MenuItem{ Crumbs: []component.MenuItem{
{Title: "Admin", Path: "/admin/"}, {Title: "Admin", Path: "/admin/"},
{Title: "Instance", Path: "*to be updated*"}, {Title: "Instance", Path: "*to be updated*"},
@ -46,7 +46,7 @@ func (admin *Admin) grants(ctx context.Context) http.Handler {
}, },
}) })
return tpl.HTMLHandlerWithGaps(func(r *http.Request, gaps *custom.BaseContextGaps) (grantsContext, error) { return tpl.HTMLHandlerWithGaps(func(r *http.Request, gaps *templates.BaseContextGaps) (grantsContext, error) {
if r.Method == http.MethodGet { if r.Method == http.MethodGet {
return admin.getGrants(r, gaps) return admin.getGrants(r, gaps)
} else { } else {
@ -55,7 +55,7 @@ func (admin *Admin) grants(ctx context.Context) http.Handler {
}) })
} }
func (admin *Admin) getGrants(r *http.Request, gaps *custom.BaseContextGaps) (gc grantsContext, err error) { func (admin *Admin) getGrants(r *http.Request, gaps *templates.BaseContextGaps) (gc grantsContext, err error) {
slug := httprouter.ParamsFromContext(r.Context()).ByName("slug") slug := httprouter.ParamsFromContext(r.Context()).ByName("slug")
if err := gc.use(r, gaps, slug, admin); err != nil { if err := gc.use(r, gaps, slug, admin); err != nil {
return gc, err return gc, err
@ -68,7 +68,7 @@ func (admin *Admin) getGrants(r *http.Request, gaps *custom.BaseContextGaps) (gc
return gc, nil return gc, nil
} }
func (admin *Admin) postGrants(r *http.Request, gaps *custom.BaseContextGaps) (gc grantsContext, err error) { func (admin *Admin) postGrants(r *http.Request, gaps *templates.BaseContextGaps) (gc grantsContext, err error) {
// parse the form // parse the form
if err := r.ParseForm(); err != nil { if err := r.ParseForm(); err != nil {
return gc, err return gc, err
@ -115,7 +115,7 @@ func (admin *Admin) postGrants(r *http.Request, gaps *custom.BaseContextGaps) (g
return gc, nil return gc, nil
} }
func (gc *grantsContext) use(r *http.Request, gaps *custom.BaseContextGaps, slug string, admin *Admin) (err error) { func (gc *grantsContext) use(r *http.Request, gaps *templates.BaseContextGaps, slug string, admin *Admin) (err error) {
gaps.Crumbs[1] = component.MenuItem{Title: "Instance", Path: template.URL("/admin/instance/" + slug)} gaps.Crumbs[1] = component.MenuItem{Title: "Instance", Path: template.URL("/admin/instance/" + slug)}
gaps.Crumbs[2] = component.MenuItem{Title: "Grants", Path: template.URL("/admin/instance/" + slug + "/grants/")} gaps.Crumbs[2] = component.MenuItem{Title: "Grants", Path: template.URL("/admin/instance/" + slug + "/grants/")}

View file

@ -8,8 +8,8 @@ import (
_ "embed" _ "embed"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component" "github.com/FAU-CDI/wisski-distillery/internal/dis/component"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/control/static" "github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/assets"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/control/static/custom" "github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/templates"
"github.com/FAU-CDI/wisski-distillery/internal/status" "github.com/FAU-CDI/wisski-distillery/internal/status"
"golang.org/x/sync/errgroup" "golang.org/x/sync/errgroup"
) )
@ -80,17 +80,17 @@ func (admin *Admin) Fetch(flags component.FetcherFlags, target *status.Distiller
//go:embed "html/index.html" //go:embed "html/index.html"
var indexHTML []byte var indexHTML []byte
var indexTemplate = custom.Parse[indexContext]("index.html", indexHTML, static.AssetsAdmin) var indexTemplate = templates.Parse[indexContext]("index.html", indexHTML, assets.AssetsAdmin)
type indexContext struct { type indexContext struct {
custom.BaseContext templates.BaseContext
status.Distillery status.Distillery
Instances []status.WissKI Instances []status.WissKI
} }
func (admin *Admin) index(ctx context.Context) http.Handler { func (admin *Admin) index(ctx context.Context) http.Handler {
tpl := indexTemplate.Prepare(admin.Dependencies.Custom, custom.BaseContextGaps{ tpl := indexTemplate.Prepare(admin.Dependencies.Templating, templates.BaseContextGaps{
Crumbs: []component.MenuItem{ Crumbs: []component.MenuItem{
{Title: "Admin", Path: "/admin/"}, {Title: "Admin", Path: "/admin/"},
}, },
@ -100,7 +100,7 @@ func (admin *Admin) index(ctx context.Context) http.Handler {
}, },
}) })
return tpl.HTMLHandlerWithGaps(func(r *http.Request, gaps *custom.BaseContextGaps) (idx indexContext, err error) { return tpl.HTMLHandlerWithGaps(func(r *http.Request, gaps *templates.BaseContextGaps) (idx indexContext, err error) {
idx.Distillery, idx.Instances, err = admin.Status(r.Context(), true) idx.Distillery, idx.Instances, err = admin.Status(r.Context(), true)
return return
}) })

View file

@ -7,9 +7,9 @@ import (
"net/http" "net/http"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component" "github.com/FAU-CDI/wisski-distillery/internal/dis/component"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/control/static"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/control/static/custom"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/instances" "github.com/FAU-CDI/wisski-distillery/internal/dis/component/instances"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/assets"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/templates"
"github.com/FAU-CDI/wisski-distillery/internal/models" "github.com/FAU-CDI/wisski-distillery/internal/models"
"github.com/FAU-CDI/wisski-distillery/internal/status" "github.com/FAU-CDI/wisski-distillery/internal/status"
"github.com/FAU-CDI/wisski-distillery/pkg/httpx" "github.com/FAU-CDI/wisski-distillery/pkg/httpx"
@ -18,17 +18,17 @@ import (
//go:embed "html/instance.html" //go:embed "html/instance.html"
var instanceHTML []byte var instanceHTML []byte
var instanceTemplate = custom.Parse[instanceContext]("instance.html", instanceHTML, static.AssetsAdmin) var instanceTemplate = templates.Parse[instanceContext]("instance.html", instanceHTML, assets.AssetsAdmin)
type instanceContext struct { type instanceContext struct {
custom.BaseContext templates.BaseContext
Instance models.Instance Instance models.Instance
Info status.WissKI Info status.WissKI
} }
func (admin *Admin) instance(ctx context.Context) http.Handler { func (admin *Admin) instance(ctx context.Context) http.Handler {
tpl := instanceTemplate.Prepare(admin.Dependencies.Custom, custom.BaseContextGaps{ tpl := instanceTemplate.Prepare(admin.Dependencies.Templating, templates.BaseContextGaps{
Crumbs: []component.MenuItem{ Crumbs: []component.MenuItem{
{Title: "Admin", Path: "/admin/"}, {Title: "Admin", Path: "/admin/"},
{Title: "Instance", Path: "*to be replaced*"}, {Title: "Instance", Path: "*to be replaced*"},
@ -39,7 +39,7 @@ func (admin *Admin) instance(ctx context.Context) http.Handler {
}, },
}) })
return tpl.HTMLHandlerWithGaps(func(r *http.Request, gaps *custom.BaseContextGaps) (ic instanceContext, err error) { return tpl.HTMLHandlerWithGaps(func(r *http.Request, gaps *templates.BaseContextGaps) (ic instanceContext, err error) {
slug := httprouter.ParamsFromContext(r.Context()).ByName("slug") slug := httprouter.ParamsFromContext(r.Context()).ByName("slug")
gaps.Crumbs[1] = component.MenuItem{Title: "Instance", Path: template.URL("/admin/instance/" + slug)} gaps.Crumbs[1] = component.MenuItem{Title: "Instance", Path: template.URL("/admin/instance/" + slug)}

View file

@ -10,8 +10,8 @@ import (
"github.com/FAU-CDI/wisski-distillery/internal/dis/component" "github.com/FAU-CDI/wisski-distillery/internal/dis/component"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/auth" "github.com/FAU-CDI/wisski-distillery/internal/dis/component/auth"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/control/static" "github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/assets"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/control/static/custom" "github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/templates"
"github.com/FAU-CDI/wisski-distillery/pkg/httpx" "github.com/FAU-CDI/wisski-distillery/pkg/httpx"
"github.com/FAU-CDI/wisski-distillery/pkg/httpx/field" "github.com/FAU-CDI/wisski-distillery/pkg/httpx/field"
"github.com/rs/zerolog" "github.com/rs/zerolog"
@ -19,17 +19,17 @@ import (
//go:embed "html/users.html" //go:embed "html/users.html"
var usersHTML []byte var usersHTML []byte
var usersTemplate = custom.Parse[usersContext]("user.html", usersHTML, static.AssetsAdmin) var usersTemplate = templates.Parse[usersContext]("user.html", usersHTML, assets.AssetsAdmin)
type usersContext struct { type usersContext struct {
custom.BaseContext templates.BaseContext
Error string Error string
Users []*auth.AuthUser Users []*auth.AuthUser
} }
func (admin *Admin) users(ctx context.Context) http.Handler { func (admin *Admin) users(ctx context.Context) http.Handler {
tpl := usersTemplate.Prepare(admin.Dependencies.Custom, custom.BaseContextGaps{ tpl := usersTemplate.Prepare(admin.Dependencies.Templating, templates.BaseContextGaps{
Crumbs: []component.MenuItem{ Crumbs: []component.MenuItem{
{Title: "Admin", Path: "/admin/"}, {Title: "Admin", Path: "/admin/"},
{Title: "Users", Path: "/admin/users/"}, {Title: "Users", Path: "/admin/users/"},
@ -48,7 +48,7 @@ func (admin *Admin) users(ctx context.Context) http.Handler {
//go:embed "html/user_create.html" //go:embed "html/user_create.html"
var userCreateHTML []byte var userCreateHTML []byte
var userCreateTemplate = custom.ParseForm("user_create.html", userCreateHTML, static.AssetsAdmin) var userCreateTemplate = templates.ParseForm("user_create.html", userCreateHTML, assets.AssetsAdmin)
var ( var (
errCreateInvalidUsername = errors.New("invalid username") errCreateInvalidUsername = errors.New("invalid username")
@ -62,7 +62,7 @@ type createUserResult struct {
} }
func (admin *Admin) createUser(ctx context.Context) http.Handler { func (admin *Admin) createUser(ctx context.Context) http.Handler {
tpl := userCreateTemplate.Prepare(admin.Dependencies.Custom, custom.BaseContextGaps{ tpl := userCreateTemplate.Prepare(admin.Dependencies.Templating, templates.BaseContextGaps{
Crumbs: []component.MenuItem{ Crumbs: []component.MenuItem{
{Title: "Admin", Path: "/admin/"}, {Title: "Admin", Path: "/admin/"},
{Title: "Users", Path: "/admin/users"}, {Title: "Users", Path: "/admin/users"},
@ -79,7 +79,7 @@ func (admin *Admin) createUser(ctx context.Context) http.Handler {
FieldTemplate: field.PureCSSFieldTemplate, FieldTemplate: field.PureCSSFieldTemplate,
RenderTemplate: tpl.Template(), RenderTemplate: tpl.Template(),
RenderTemplateContext: custom.FormTemplateContext(tpl), RenderTemplateContext: templates.FormTemplateContext(tpl),
Validate: func(r *http.Request, values map[string]string) (cu createUserResult, err error) { Validate: func(r *http.Request, values map[string]string) (cu createUserResult, err error) {
cu.User, cu.Passsword, cu.Admin = values["username"], values["password"], values["admin"] == field.CheckboxChecked cu.User, cu.Passsword, cu.Admin = values["username"], values["password"], values["admin"] == field.CheckboxChecked

View file

@ -1,4 +1,4 @@
package static package assets
import ( import (
"html/template" "html/template"
@ -13,7 +13,7 @@ import (
// - Delete any previously generated distribution directory. // - Delete any previously generated distribution directory.
// - Bundle the entrypoint sources under 'src/entry/{{Name}}/index.{ts,css}' together with the base './src/base/index.{ts,css}' // - Bundle the entrypoint sources under 'src/entry/{{Name}}/index.{ts,css}' together with the base './src/base/index.{ts,css}'
// - Store the output inside the 'dist' directory // - Store the output inside the 'dist' directory
// - Generate new constants of the form {{Name}} // - Generate new constants of the form Assets{{Name}}
// //
// Each asset group should be registered as a parameter to the 'go:generate' line. // Each asset group should be registered as a parameter to the 'go:generate' line.
type Assets struct { type Assets struct {

View file

@ -0,0 +1,29 @@
package assets
import _ "embed"
// This file was automatically generated. Do not edit.
//go:embed "assets_disclaimer.txt"
var Disclaimer string
// Public holds the path to the public route
const Public = "/this-is-fine/"
// AssetsDefault contains assets for the 'Default' entrypoint.
var AssetsDefault = Assets{
Scripts: `<script type="module" src="/this-is-fine/Default.38d394c2.js"></script><script src="/this-is-fine/Default.38d394c2.js" nomodule="" defer></script><script type="module" src="/this-is-fine/Default.38d394c2.js"></script><script src="/this-is-fine/Default.38d394c2.js" nomodule="" defer></script>`,
Styles: `<link rel="stylesheet" href="/this-is-fine/Default.db26a303.css"><link rel="stylesheet" href="/this-is-fine/Default.f9675eae.css">`,
}
// AssetsUser contains assets for the 'User' entrypoint.
var AssetsUser = Assets{
Scripts: `<script type="module" src="/this-is-fine/Default.38d394c2.js"></script><script src="/this-is-fine/Default.38d394c2.js" nomodule="" defer></script><script type="module" src="/this-is-fine/User.e0367d79.js"></script><script src="/this-is-fine/User.b2f9a57c.js" nomodule="" defer></script>`,
Styles: `<link rel="stylesheet" href="/this-is-fine/Default.db26a303.css"><link rel="stylesheet" href="/this-is-fine/User.68febbf8.css"><link rel="stylesheet" href="/this-is-fine/User.840de3b4.css">`,
}
// AssetsAdmin contains assets for the 'Admin' entrypoint.
var AssetsAdmin = Assets{
Scripts: `<script nomodule="" defer src="/this-is-fine/User.b2f9a57c.js"></script><script type="module" src="/this-is-fine/User.e0367d79.js"></script><script type="module" src="/this-is-fine/Default.38d394c2.js"></script><script src="/this-is-fine/Default.38d394c2.js" nomodule="" defer></script><script type="module" src="/this-is-fine/Admin.1a380f6f.js"></script><script src="/this-is-fine/Admin.cb58d290.js" nomodule="" defer></script>`,
Styles: `<link rel="stylesheet" href="/this-is-fine/Default.db26a303.css"><link rel="stylesheet" href="/this-is-fine/Admin.6d59e220.css"><link rel="stylesheet" href="/this-is-fine/User.840de3b4.css"><link rel="stylesheet" href="/this-is-fine/User.68febbf8.css"><link rel="stylesheet" href="/this-is-fine/Admin.6d2ae968.css">`,
}

View file

@ -11,7 +11,7 @@ import { spawnSync } from 'child_process'
const ENTRYPOINTS = process.argv.slice(2) const ENTRYPOINTS = process.argv.slice(2)
const ENTRY_DIR = join('.', '.entry-cache') // directory to place entries into const ENTRY_DIR = join('.', '.entry-cache') // directory to place entries into
const DIST_DIR = join('.', 'dist') const DIST_DIR = join('.', 'dist')
const PUBLIC_DIR = '/static/' const PUBLIC_DIR = '/this-is-fine/'
const DEST_PACKAGE = process.env.GOPACKAGE ?? 'static' const DEST_PACKAGE = process.env.GOPACKAGE ?? 'static'
const DEST_DISCLAIMER = (() => { const DEST_DISCLAIMER = (() => {
@ -152,7 +152,10 @@ import _ "embed"
// This file was automatically generated. Do not edit. // This file was automatically generated. Do not edit.
//go:embed ${JSON.stringify(DEST_DISCLAIMER)} //go:embed ${JSON.stringify(DEST_DISCLAIMER)}
var AssetsDisclaimer string var Disclaimer string
// Public holds the path to the public route
const Public = ${JSON.stringify(PUBLIC_DIR)}
${goAssets} ${goAssets}
`; `;

View file

@ -1,5 +1,5 @@
// Package static implements serving of fully static resources // Package static implements serving of fully static resources
package static package assets
import ( import (
"context" "context"
@ -20,7 +20,7 @@ var (
func (*Static) Routes() component.Routes { func (*Static) Routes() component.Routes {
return component.Routes{ return component.Routes{
Prefix: "/static/", Prefix: Public,
CSRF: false, CSRF: false,
} }

View file

@ -1,8 +1,7 @@
package static package assets
import ( import (
"embed" "embed"
"encoding/json"
"html/template" "html/template"
) )
@ -17,12 +16,6 @@ var (
// It will be able to make use of shared templates as well as functions. // It will be able to make use of shared templates as well as functions.
func NewSharedTemplate(name string) *template.Template { func NewSharedTemplate(name string) *template.Template {
new := template.New(name) new := template.New(name)
new.Funcs(template.FuncMap{
"json": func(data any) (string, error) {
bytes, err := json.Marshal(data)
return string(bytes), err
},
})
for _, template := range shared.Templates() { for _, template := range shared.Templates() {
new.AddParseTree(template.Tree.Name, template.Tree.Copy()) new.AddParseTree(template.Tree.Name, template.Tree.Copy())
} }

View file

@ -44,7 +44,7 @@
<footer> <footer>
{{ block "@custom/footer" .BaseContext }} {{ block "@custom/footer" .BaseContext }}
<div style="z-index:10000;position:fixed;top:0;left:0;width:100vh;height:100vw;background:red;text-align:center;padding:10vh 10vw;font-size:xx-large;font-weight:bold"> <div style="z-index:10000;position:fixed;top:0;left:0;width:100vh;height:100vw;background:red;text-align:center;padding:10vh 10vw;font-size:xx-large;font-weight:bold">
<code>.Custom.Template()</code> not called <code>.Templating.Template()</code> not called
</div> </div>
{{ end }} {{ end }}
</footer> </footer>

View file

@ -1,4 +1,4 @@
package control package server
// CSRFCookie, CSRFCookieField, SessionCookie and SessionUserKey // CSRFCookie, CSRFCookieField, SessionCookie and SessionUserKey
// hold the names of the cookies and fields used for specific cookies. // hold the names of the cookies and fields used for specific cookies.

View file

@ -6,8 +6,8 @@ import (
"net/http" "net/http"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component" "github.com/FAU-CDI/wisski-distillery/internal/dis/component"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/control/static/custom"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/instances" "github.com/FAU-CDI/wisski-distillery/internal/dis/component/instances"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/templates"
"github.com/FAU-CDI/wisski-distillery/internal/status" "github.com/FAU-CDI/wisski-distillery/internal/status"
"github.com/FAU-CDI/wisski-distillery/pkg/lazy" "github.com/FAU-CDI/wisski-distillery/pkg/lazy"
) )
@ -15,8 +15,8 @@ import (
type Home struct { type Home struct {
component.Base component.Base
Dependencies struct { Dependencies struct {
Templating *templates.Templating
Instances *instances.Instances Instances *instances.Instances
Custom *custom.Custom
} }
instanceNames lazy.Lazy[map[string]struct{}] // instance names instanceNames lazy.Lazy[map[string]struct{}] // instance names

View file

@ -7,25 +7,25 @@ import (
"strings" "strings"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component" "github.com/FAU-CDI/wisski-distillery/internal/dis/component"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/control/static" "github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/assets"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/control/static/custom" "github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/templates"
"github.com/FAU-CDI/wisski-distillery/internal/status" "github.com/FAU-CDI/wisski-distillery/internal/status"
"github.com/FAU-CDI/wisski-distillery/pkg/httpx" "github.com/FAU-CDI/wisski-distillery/pkg/httpx"
) )
//go:embed "public.html" //go:embed "public.html"
var publicHTML []byte var publicHTML []byte
var publicTemplate = custom.Parse[publicContext]("public.html", publicHTML, static.AssetsDefault) var publicTemplate = templates.Parse[publicContext]("public.html", publicHTML, assets.AssetsDefault)
type publicContext struct { type publicContext struct {
custom.BaseContext templates.BaseContext
Instances []status.WissKI Instances []status.WissKI
SelfRedirect string SelfRedirect string
} }
func (home *Home) publicHandler(ctx context.Context) http.Handler { func (home *Home) publicHandler(ctx context.Context) http.Handler {
tpl := publicTemplate.Prepare(home.Dependencies.Custom, custom.BaseContextGaps{ tpl := publicTemplate.Prepare(home.Dependencies.Templating, templates.BaseContextGaps{
Crumbs: []component.MenuItem{ Crumbs: []component.MenuItem{
{Title: "WissKI Distillery", Path: "/"}, {Title: "WissKI Distillery", Path: "/"},
}, },

View file

@ -6,9 +6,9 @@ import (
"github.com/FAU-CDI/wisski-distillery/internal/cli" "github.com/FAU-CDI/wisski-distillery/internal/cli"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component" "github.com/FAU-CDI/wisski-distillery/internal/dis/component"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/control" "github.com/FAU-CDI/wisski-distillery/internal/dis/component/server"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/control/static" "github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/assets"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/control/static/custom" "github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/templates"
_ "embed" _ "embed"
) )
@ -16,8 +16,8 @@ import (
type Legal struct { type Legal struct {
component.Base component.Base
Dependencies struct { Dependencies struct {
Static *static.Static Static *assets.Static
Custom *custom.Custom Templating *templates.Templating
} }
} }
@ -27,10 +27,10 @@ var (
//go:embed "legal.html" //go:embed "legal.html"
var legalHTML []byte var legalHTML []byte
var legalTemplate = custom.Parse[legalContext]("legal.html", legalHTML, static.AssetsDefault) var legalTemplate = templates.Parse[legalContext]("legal.html", legalHTML, assets.AssetsDefault)
type legalContext struct { type legalContext struct {
custom.BaseContext templates.BaseContext
LegalNotices string LegalNotices string
@ -49,7 +49,7 @@ func (legal *Legal) Routes() component.Routes {
} }
func (legal *Legal) HandleRoute(ctx context.Context, route string) (http.Handler, error) { func (legal *Legal) HandleRoute(ctx context.Context, route string) (http.Handler, error) {
tpl := legalTemplate.Prepare(legal.Dependencies.Custom, custom.BaseContextGaps{ tpl := legalTemplate.Prepare(legal.Dependencies.Templating, templates.BaseContextGaps{
Crumbs: []component.MenuItem{ Crumbs: []component.MenuItem{
{Title: "Legal", Path: "/legal/"}, {Title: "Legal", Path: "/legal/"},
}, },
@ -58,9 +58,9 @@ func (legal *Legal) HandleRoute(ctx context.Context, route string) (http.Handler
return tpl.HTMLHandler(func(r *http.Request) (lc legalContext, err error) { return tpl.HTMLHandler(func(r *http.Request) (lc legalContext, err error) {
lc.LegalNotices = cli.LegalNotices lc.LegalNotices = cli.LegalNotices
lc.CSRFCookie = control.CSRFCookie lc.CSRFCookie = server.CSRFCookie
lc.SessionCookie = control.SessionCookie lc.SessionCookie = server.SessionCookie
lc.AssetsDisclaimer = static.AssetsDisclaimer lc.AssetsDisclaimer = assets.Disclaimer
return return
}), nil }), nil

View file

@ -10,8 +10,8 @@ import (
"time" "time"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component" "github.com/FAU-CDI/wisski-distillery/internal/dis/component"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/control/static" "github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/assets"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/control/static/custom" "github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/templates"
"github.com/rs/zerolog" "github.com/rs/zerolog"
"github.com/yuin/goldmark" "github.com/yuin/goldmark"
gmmeta "github.com/yuin/goldmark-meta" gmmeta "github.com/yuin/goldmark-meta"
@ -22,7 +22,7 @@ import (
type News struct { type News struct {
component.Base component.Base
Dependencies struct { Dependencies struct {
Custom *custom.Custom Templating *templates.Templating
} }
} }
@ -113,16 +113,16 @@ func Items() ([]Item, error) {
//go:embed "news.html" //go:embed "news.html"
var newsHTML []byte var newsHTML []byte
var newsTemplate = custom.Parse[newsContext]("news.html", newsHTML, static.AssetsDefault) var newsTemplate = templates.Parse[newsContext]("news.html", newsHTML, assets.AssetsDefault)
type newsContext struct { type newsContext struct {
custom.BaseContext templates.BaseContext
Items []Item Items []Item
} }
// HandleRoute returns the handler for the requested path // HandleRoute returns the handler for the requested path
func (news *News) HandleRoute(ctx context.Context, path string) (http.Handler, error) { func (news *News) HandleRoute(ctx context.Context, path string) (http.Handler, error) {
tpl := newsTemplate.Prepare(news.Dependencies.Custom, custom.BaseContextGaps{ tpl := newsTemplate.Prepare(news.Dependencies.Templating, templates.BaseContextGaps{
Crumbs: []component.MenuItem{ Crumbs: []component.MenuItem{
{Title: "News", Path: "/news/"}, {Title: "News", Path: "/news/"},
}, },

View file

@ -1,4 +1,4 @@
package control package server
import ( import (
"context" "context"
@ -7,6 +7,7 @@ import (
"net/http" "net/http"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component" "github.com/FAU-CDI/wisski-distillery/internal/dis/component"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/templates"
"github.com/FAU-CDI/wisski-distillery/pkg/cancel" "github.com/FAU-CDI/wisski-distillery/pkg/cancel"
"github.com/FAU-CDI/wisski-distillery/pkg/httpx" "github.com/FAU-CDI/wisski-distillery/pkg/httpx"
"github.com/FAU-CDI/wisski-distillery/pkg/mux" "github.com/FAU-CDI/wisski-distillery/pkg/mux"
@ -14,16 +15,31 @@ import (
"github.com/rs/zerolog" "github.com/rs/zerolog"
) )
// Server represents the running control server.
type Server struct {
component.Base
Dependencies struct {
Routeables []component.Routeable
Cronables []component.Cronable
Templating *templates.Templating
}
}
var (
_ component.Installable = (*Server)(nil)
)
// Server returns an http.Mux that implements the main server instance. // Server returns an http.Mux that implements the main server instance.
// The server may spawn background tasks, but these should be terminated once context closes. // The server may spawn background tasks, but these should be terminated once context closes.
// //
// Logging messages are directed to progress // Logging messages are directed to progress
func (control *Control) Server(ctx context.Context, progress io.Writer) (public http.Handler, internal http.Handler, err error) { func (server *Server) Server(ctx context.Context, progress io.Writer) (public http.Handler, internal http.Handler, err error) {
logger := zerolog.Ctx(ctx) logger := zerolog.Ctx(ctx)
var publicM, internalM mux.Mux[component.RouteContext] var publicM, internalM mux.Mux[component.RouteContext]
publicM.Context = func(r *http.Request) component.RouteContext { publicM.Context = func(r *http.Request) component.RouteContext {
slug, ok := control.Still.Config.SlugFromHost(r.Host) slug, ok := server.Still.Config.SlugFromHost(r.Host)
return component.RouteContext{ return component.RouteContext{
DefaultDomain: slug == "" && ok, DefaultDomain: slug == "" && ok,
} }
@ -44,10 +60,10 @@ func (control *Control) Server(ctx context.Context, progress io.Writer) (public
internalM.Context = publicM.Context internalM.Context = publicM.Context
// create a csrf protector // create a csrf protector
csrfProtector := control.CSRF() csrfProtector := server.csrf()
// iterate over all the handler // iterate over all the handler
for _, s := range control.Dependencies.Routeables { for _, s := range server.Dependencies.Routeables {
routes := s.Routes() routes := s.Routes()
zerolog.Ctx(ctx).Info(). zerolog.Ctx(ctx).Info().
Str("Name", s.Name()). Str("Name", s.Name()).
@ -94,13 +110,13 @@ func (control *Control) Server(ctx context.Context, progress io.Writer) (public
} }
// CSRF returns a CSRF handler for the given function // CSRF returns a CSRF handler for the given function
func (control *Control) CSRF() func(http.Handler) http.Handler { func (server *Server) csrf() func(http.Handler) http.Handler {
var opts []csrf.Option var opts []csrf.Option
if !control.Config.HTTPSEnabled() { if !server.Config.HTTPSEnabled() {
opts = append(opts, csrf.Secure(false)) opts = append(opts, csrf.Secure(false))
} }
opts = append(opts, csrf.SameSite(csrf.SameSiteStrictMode)) opts = append(opts, csrf.SameSite(csrf.SameSiteStrictMode))
opts = append(opts, csrf.CookieName(CSRFCookie)) opts = append(opts, csrf.CookieName(CSRFCookie))
opts = append(opts, csrf.FieldName(CSRFCookieField)) opts = append(opts, csrf.FieldName(CSRFCookieField))
return csrf.Protect(control.Config.CSRFSecret(), opts...) return csrf.Protect(server.Config.CSRFSecret(), opts...)
} }

View file

@ -0,0 +1,55 @@
package server
import (
"context"
"embed"
"io"
"path/filepath"
"syscall"
"github.com/FAU-CDI/wisski-distillery/internal/bootstrap"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
"github.com/FAU-CDI/wisski-distillery/pkg/environment"
)
func (control Server) Path() string {
return filepath.Join(control.Still.Config.DeployRoot, "core", "dis")
}
//go:embed all:server server.env
var resources embed.FS
func (server *Server) Stack(env environment.Environment) component.StackWithResources {
return component.MakeStack(server, env, component.StackWithResources{
Resources: resources,
ContextPath: "server",
EnvPath: "server.env",
EnvContext: map[string]string{
"DOCKER_NETWORK_NAME": server.Config.DockerNetworkName,
"HOST_RULE": server.Config.DefaultHostRule(),
"HTTPS_ENABLED": server.Config.HTTPSEnabledEnv(),
"CONFIG_PATH": server.Config.ConfigPath,
"DEPLOY_ROOT": server.Config.DeployRoot,
"SELF_OVERRIDES_FILE": server.Config.SelfOverridesFile,
"SELF_RESOLVER_BLOCK_FILE": server.Config.SelfResolverBlockFile,
"CUSTOM_ASSETS_PATH": server.Dependencies.Templating.CustomAssetsPath(),
},
CopyContextFiles: []string{bootstrap.Executable},
})
}
// Trigger triggers the active cron run to immediatly invoke cron.
func (server *Server) Trigger(ctx context.Context, env environment.Environment) error {
return server.Stack(env).Kill(ctx, io.Discard, "control", syscall.SIGHUP)
}
func (server *Server) Context(parent component.InstallationContext) component.InstallationContext {
return component.InstallationContext{
bootstrap.Executable: server.Config.CurrentExecutable(server.Environment), // TODO: Does this make sense?
}
}

View file

@ -0,0 +1,22 @@
package templates
import (
"path/filepath"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
)
// CustomAssetsPath is the path custom assets are stored at
func (tpl *Templating) CustomAssetsPath() string {
return filepath.Join(tpl.Config.DeployRoot, "core", "assets")
}
func (tpl *Templating) CustomAssetPath(name string) string {
return filepath.Join(tpl.CustomAssetsPath(), name)
}
func (tpl *Templating) BackupName() string { return "custom" }
func (tpl *Templating) Backup(context component.StagingContext) error {
return context.CopyDirectory("", tpl.CustomAssetsPath())
}

View file

@ -1,4 +1,4 @@
package custom package templates
import ( import (
"html/template" "html/template"
@ -16,9 +16,8 @@ import (
// baseContextName is the name of the [BaseContext] type // baseContextName is the name of the [BaseContext] type
var baseContextName = reflectx.TypeOf[BaseContext]().Name() var baseContextName = reflectx.TypeOf[BaseContext]().Name()
// BaseContext represents a context shared by all the templates. // BaseContext represents a context used by templates
// //
// This context should always be initialized using the [custom.Update], [custom.New] or [custom.NewForm] functions.
// Other invocations might cause an error at runtime. // Other invocations might cause an error at runtime.
type BaseContext struct { type BaseContext struct {
inited bool // has this context been inited? inited bool // has this context been inited?
@ -56,11 +55,11 @@ func (bcg BaseContextGaps) clone() BaseContextGaps {
} }
// update updates an embedded BaseContext field in context. // update updates an embedded BaseContext field in context.
func (custom *Custom) update(context any, r *http.Request, bcg BaseContextGaps) *BaseContext { func (tpl *Templating) update(context any, r *http.Request, bcg BaseContextGaps) *BaseContext {
tc := reflect.ValueOf(context). tc := reflect.ValueOf(context).
Elem().FieldByName(baseContextName).Addr(). Elem().FieldByName(baseContextName).Addr().
Interface().(*BaseContext) Interface().(*BaseContext)
// tc.custom = custom
tc.inited = true tc.inited = true
tc.requestWasNil = r == nil tc.requestWasNil = r == nil
@ -73,7 +72,7 @@ func (custom *Custom) update(context any, r *http.Request, bcg BaseContextGaps)
} }
// build the menu // build the menu
tc.Menu = custom.BuildMenu(r) tc.Menu = tpl.buildMenu(r)
// build the breadcrumbs // build the breadcrumbs
tc.BaseContextGaps = bcg.clone() tc.BaseContextGaps = bcg.clone()

Some files were not shown because too many files have changed in this diff Show more