Update to new goprogram version
This commit is contained in:
parent
7bd9570bc0
commit
873fdcd5c2
106 changed files with 478 additions and 825 deletions
4
go.mod
4
go.mod
|
|
@ -15,8 +15,8 @@ require (
|
||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
github.com/pquerna/otp v1.4.0
|
github.com/pquerna/otp v1.4.0
|
||||||
github.com/rs/zerolog v1.31.0
|
github.com/rs/zerolog v1.31.0
|
||||||
github.com/tkw1536/goprogram v0.4.1
|
github.com/tkw1536/goprogram v0.5.0
|
||||||
github.com/tkw1536/pkglib v0.0.0-20230719003505-d3ee10877e75
|
github.com/tkw1536/pkglib v0.0.0-20231102105724-b30af08a5e61
|
||||||
github.com/yuin/goldmark v1.6.0
|
github.com/yuin/goldmark v1.6.0
|
||||||
github.com/yuin/goldmark-meta v1.1.0
|
github.com/yuin/goldmark-meta v1.1.0
|
||||||
golang.org/x/crypto v0.14.0
|
golang.org/x/crypto v0.14.0
|
||||||
|
|
|
||||||
8
go.sum
8
go.sum
|
|
@ -115,10 +115,10 @@ github.com/tdewolff/parse v2.3.4+incompatible h1:x05/cnGwIMf4ceLuDMBOdQ1qGniMoxp
|
||||||
github.com/tdewolff/parse v2.3.4+incompatible/go.mod h1:8oBwCsVmUkgHO8M5iCzSIDtpzXOT0WXX9cWhz+bIzJQ=
|
github.com/tdewolff/parse v2.3.4+incompatible/go.mod h1:8oBwCsVmUkgHO8M5iCzSIDtpzXOT0WXX9cWhz+bIzJQ=
|
||||||
github.com/tdewolff/test v1.0.7 h1:8Vs0142DmPFW/bQeHRP3MV19m1gvndjUb1sn8yy74LM=
|
github.com/tdewolff/test v1.0.7 h1:8Vs0142DmPFW/bQeHRP3MV19m1gvndjUb1sn8yy74LM=
|
||||||
github.com/tdewolff/test v1.0.7/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE=
|
github.com/tdewolff/test v1.0.7/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE=
|
||||||
github.com/tkw1536/goprogram v0.4.1 h1:ttJ4xyuflmSU4QJ85gPmViCfUZPe3okxhWfvx75Dk/E=
|
github.com/tkw1536/goprogram v0.5.0 h1:7vcIjmMdcZPJyRhgdlCaGfHAoOG3oYlFrno1pWXy1Bs=
|
||||||
github.com/tkw1536/goprogram v0.4.1/go.mod h1:HIePHXDI5tHPZJ3jmC6yiiYaMAUUvkvjEEj2WSdCt9c=
|
github.com/tkw1536/goprogram v0.5.0/go.mod h1:MDCwqLmvcc2QryMm6oSC9h/QAdE9PewZ2Mp2Lm7MmAg=
|
||||||
github.com/tkw1536/pkglib v0.0.0-20230719003505-d3ee10877e75 h1:OM/hHYpCfa/wt/rO6JHOaBSjJkP5xQi+Glu9ZGzRuwA=
|
github.com/tkw1536/pkglib v0.0.0-20231102105724-b30af08a5e61 h1:kj2iTWUtfXyeiK7CoGsd0wBof+Py6pXvDUI7aDZaZIc=
|
||||||
github.com/tkw1536/pkglib v0.0.0-20230719003505-d3ee10877e75/go.mod h1:0A1B9Cc5+yJXR3eeB14CqD4dFSbEjjWRo5Pr9M3XYuI=
|
github.com/tkw1536/pkglib v0.0.0-20231102105724-b30af08a5e61/go.mod h1:vbJxEej2lPJXsFUxTGPK+nREnQOOyiBGdWL0kuzpsDQ=
|
||||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo=
|
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo=
|
||||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||||
|
|
|
||||||
|
|
@ -1,75 +1 @@
|
||||||
package dis
|
package dis
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
|
||||||
"github.com/tkw1536/pkglib/collection"
|
|
||||||
"github.com/tkw1536/pkglib/lifetime"
|
|
||||||
)
|
|
||||||
|
|
||||||
//
|
|
||||||
// ==== init ====
|
|
||||||
//
|
|
||||||
|
|
||||||
func (dis *Distillery) init() {
|
|
||||||
dis.lifetimeInit.Do(func() {
|
|
||||||
dis.lifetime.Init = component.Init
|
|
||||||
|
|
||||||
lifetime.RegisterGroup[component.Backupable](&dis.lifetime)
|
|
||||||
lifetime.RegisterGroup[component.Snapshotable](&dis.lifetime)
|
|
||||||
lifetime.RegisterGroup[component.DistilleryFetcher](&dis.lifetime)
|
|
||||||
lifetime.RegisterGroup[component.Installable](&dis.lifetime)
|
|
||||||
lifetime.RegisterGroup[component.Provisionable](&dis.lifetime)
|
|
||||||
lifetime.RegisterGroup[component.Routeable](&dis.lifetime)
|
|
||||||
lifetime.RegisterGroup[component.Cronable](&dis.lifetime)
|
|
||||||
lifetime.RegisterGroup[component.UserDeleteHook](&dis.lifetime)
|
|
||||||
lifetime.RegisterGroup[component.Table](&dis.lifetime)
|
|
||||||
lifetime.RegisterGroup[component.Menuable](&dis.lifetime)
|
|
||||||
lifetime.RegisterGroup[component.ScopeProvider](&dis.lifetime)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// ==== registration ====
|
|
||||||
//
|
|
||||||
|
|
||||||
// manual initializes a component from the provided distillery.
|
|
||||||
func manual[C component.Component](init func(component C)) initFunc {
|
|
||||||
return func(context ctx) component.Component {
|
|
||||||
return lifetime.Make(context, init)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// use is like r, but does not provided additional initialization
|
|
||||||
func auto[C component.Component](context ctx) component.Component {
|
|
||||||
return lifetime.Make[component.Component, C](context, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
// register returns all components of the distillery
|
|
||||||
func (dis *Distillery) register(context ctx) []component.Component {
|
|
||||||
return collection.MapSlice(
|
|
||||||
dis.allComponents(),
|
|
||||||
func(f initFunc) component.Component {
|
|
||||||
return f(context)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ctx is a context for component initialization
|
|
||||||
type ctx = *lifetime.InjectorContext[component.Component]
|
|
||||||
|
|
||||||
//
|
|
||||||
// ==== export ====
|
|
||||||
//
|
|
||||||
|
|
||||||
// export is a convenience function to export a single component
|
|
||||||
func export[C component.Component](dis *Distillery) C {
|
|
||||||
dis.init()
|
|
||||||
return lifetime.ExportComponent[component.Component, component.Still, C](&dis.lifetime, dis.Still, dis.register)
|
|
||||||
}
|
|
||||||
|
|
||||||
func exportAll[C component.Component](dis *Distillery) []C {
|
|
||||||
dis.init()
|
|
||||||
return lifetime.ExportComponents[component.Component, component.Still, C](&dis.lifetime, dis.Still, dis.register)
|
|
||||||
}
|
|
||||||
|
|
||||||
type initFunc = func(context ctx) component.Component
|
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import (
|
||||||
|
|
||||||
type API struct {
|
type API struct {
|
||||||
component.Base
|
component.Base
|
||||||
Dependencies struct {
|
dependencies struct {
|
||||||
Auth *auth.Auth
|
Auth *auth.Auth
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -38,12 +38,12 @@ type AuthInfo struct {
|
||||||
func (a *API) HandleRoute(ctx context.Context, path string) (http.Handler, error) {
|
func (a *API) HandleRoute(ctx context.Context, path string) (http.Handler, error) {
|
||||||
return &Handler[AuthInfo]{
|
return &Handler[AuthInfo]{
|
||||||
Config: a.Config,
|
Config: a.Config,
|
||||||
Auth: a.Dependencies.Auth,
|
Auth: a.dependencies.Auth,
|
||||||
|
|
||||||
Methods: []string{"GET"},
|
Methods: []string{"GET"},
|
||||||
|
|
||||||
Handler: func(s string, r *http.Request) (ai AuthInfo, err error) {
|
Handler: func(s string, r *http.Request) (ai AuthInfo, err error) {
|
||||||
session, _, err := a.Dependencies.Auth.SessionOf(r)
|
session, _, err := a.dependencies.Auth.SessionOf(r)
|
||||||
ai.User = session.Username()
|
ai.User = session.Username()
|
||||||
ai.Token = session.Token
|
ai.Token = session.Token
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ import (
|
||||||
|
|
||||||
type Auth struct {
|
type Auth struct {
|
||||||
component.Base
|
component.Base
|
||||||
Dependencies struct {
|
dependencies struct {
|
||||||
SQL *sql.SQL
|
SQL *sql.SQL
|
||||||
UserDeleteHooks []component.UserDeleteHook
|
UserDeleteHooks []component.UserDeleteHook
|
||||||
Templating *templating.Templating
|
Templating *templating.Templating
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ import (
|
||||||
|
|
||||||
type Next struct {
|
type Next struct {
|
||||||
component.Base
|
component.Base
|
||||||
Dependencies struct {
|
dependencies struct {
|
||||||
Auth *auth.Auth
|
Auth *auth.Auth
|
||||||
Policy *policy.Policy
|
Policy *policy.Policy
|
||||||
Instances *instances.Instances
|
Instances *instances.Instances
|
||||||
|
|
@ -31,13 +31,13 @@ var (
|
||||||
func (next *Next) Routes() component.Routes {
|
func (next *Next) Routes() component.Routes {
|
||||||
return component.Routes{
|
return component.Routes{
|
||||||
Prefix: "/next/",
|
Prefix: "/next/",
|
||||||
Decorator: next.Dependencies.Auth.Require(true, scopes.ScopeUserValid, nil),
|
Decorator: next.dependencies.Auth.Require(true, scopes.ScopeUserValid, nil),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Next returns a url that will forward authorized users to the given slug and path
|
// Next returns a url that will forward authorized users to the given slug and path
|
||||||
func (next *Next) Next(context context.Context, slug, path string) (string, error) {
|
func (next *Next) Next(context context.Context, slug, path string) (string, error) {
|
||||||
wisski, err := next.Dependencies.Instances.WissKI(context, slug)
|
wisski, err := next.dependencies.Instances.WissKI(context, slug)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
@ -62,7 +62,7 @@ func (next *Next) getInstance(r *http.Request) (wisski *wisski.WissKI, path stri
|
||||||
}
|
}
|
||||||
|
|
||||||
// fetch the instance from the database
|
// fetch the instance from the database
|
||||||
wisski, err = next.Dependencies.Instances.WissKI(r.Context(), slug)
|
wisski, err = next.dependencies.Instances.WissKI(r.Context(), slug)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, "", err
|
return nil, "", err
|
||||||
}
|
}
|
||||||
|
|
@ -80,13 +80,13 @@ func (next *Next) HandleRoute(ctx context.Context, path string) (http.Handler, e
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the user
|
// get the user
|
||||||
user, _, err := next.Dependencies.Auth.SessionOf(r)
|
user, _, err := next.dependencies.Auth.SessionOf(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", 0, err
|
return "", 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if they have a grant
|
// check if they have a grant
|
||||||
grant, err := next.Dependencies.Policy.Has(r.Context(), user.User.User, instance.Slug)
|
grant, err := next.dependencies.Policy.Has(r.Context(), user.User.User, instance.Slug)
|
||||||
if err == policy.ErrNoAccess {
|
if err == policy.ErrNoAccess {
|
||||||
return "", 0, httpx.ErrForbidden
|
return "", 0, httpx.ErrForbidden
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ import (
|
||||||
|
|
||||||
type UserPanel struct {
|
type UserPanel struct {
|
||||||
component.Base
|
component.Base
|
||||||
Dependencies struct {
|
dependencies struct {
|
||||||
Auth *auth.Auth
|
Auth *auth.Auth
|
||||||
Templating *templating.Templating
|
Templating *templating.Templating
|
||||||
Policy *policy.Policy
|
Policy *policy.Policy
|
||||||
|
|
@ -42,14 +42,14 @@ func (panel *UserPanel) Routes() component.Routes {
|
||||||
return component.Routes{
|
return component.Routes{
|
||||||
Prefix: "/user/",
|
Prefix: "/user/",
|
||||||
CSRF: true,
|
CSRF: true,
|
||||||
Decorator: panel.Dependencies.Auth.Require(false, scopes.ScopeUserValid, nil),
|
Decorator: panel.dependencies.Auth.Require(false, scopes.ScopeUserValid, nil),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (panel *UserPanel) Menu(r *http.Request) []component.MenuItem {
|
func (panel *UserPanel) Menu(r *http.Request) []component.MenuItem {
|
||||||
title := "Login"
|
title := "Login"
|
||||||
|
|
||||||
user, err := panel.Dependencies.Auth.UserOfSession(r)
|
user, err := panel.dependencies.Auth.UserOfSession(r)
|
||||||
if user != nil && err == nil {
|
if user != nil && err == nil {
|
||||||
title = user.User.User
|
title = user.User.User
|
||||||
}
|
}
|
||||||
|
|
@ -137,7 +137,7 @@ func (panel *UserPanel) HandleRoute(ctx context.Context, route string) (http.Han
|
||||||
}
|
}
|
||||||
|
|
||||||
// ensure that the user is logged in!
|
// ensure that the user is logged in!
|
||||||
return panel.Dependencies.Auth.Protect(router, false, scopes.ScopeUserValid, nil), nil
|
return panel.dependencies.Auth.Protect(router, false, scopes.ScopeUserValid, nil), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type userFormContext struct {
|
type userFormContext struct {
|
||||||
|
|
@ -158,7 +158,7 @@ func (panel *UserPanel) UserFormContext(tpl *templating.Template[userFormContext
|
||||||
|
|
||||||
return func(ctx httpx.FormContext, r *http.Request) any {
|
return func(ctx httpx.FormContext, r *http.Request) any {
|
||||||
uctx := userFormContext{FormContext: ctx}
|
uctx := userFormContext{FormContext: ctx}
|
||||||
if user, err := panel.Dependencies.Auth.UserOfSession(r); err == nil {
|
if user, err := panel.dependencies.Auth.UserOfSession(r); err == nil {
|
||||||
uctx.User = &user.User
|
uctx.User = &user.User
|
||||||
}
|
}
|
||||||
return tpl.Context(r, uctx, funcs...)
|
return tpl.Context(r, uctx, funcs...)
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,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.Templating)
|
tpl := passwordTemplate.Prepare(panel.dependencies.Templating)
|
||||||
|
|
||||||
return &httpx.Form[struct{}]{
|
return &httpx.Form[struct{}]{
|
||||||
Fields: []field.Field{
|
Fields: []field.Field{
|
||||||
|
|
@ -53,7 +53,7 @@ func (panel *UserPanel) routePassword(ctx context.Context) http.Handler {
|
||||||
return struct{}{}, errPasswordsNotIdentical
|
return struct{}{}, errPasswordsNotIdentical
|
||||||
}
|
}
|
||||||
|
|
||||||
user, err := panel.Dependencies.Auth.UserOfSession(r)
|
user, err := panel.dependencies.Auth.UserOfSession(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return struct{}{}, err
|
return struct{}{}, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,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(
|
tpl := sshTemplate.Prepare(
|
||||||
panel.Dependencies.Templating,
|
panel.dependencies.Templating,
|
||||||
templating.Crumbs(
|
templating.Crumbs(
|
||||||
menuUser,
|
menuUser,
|
||||||
menuSSH,
|
menuSSH,
|
||||||
|
|
@ -57,7 +57,7 @@ func (panel *UserPanel) sshRoute(ctx context.Context) http.Handler {
|
||||||
)
|
)
|
||||||
|
|
||||||
return tpl.HTMLHandler(func(r *http.Request) (sc SSHTemplateContext, err error) {
|
return tpl.HTMLHandler(func(r *http.Request) (sc SSHTemplateContext, err error) {
|
||||||
user, err := panel.Dependencies.Auth.UserOfSession(r)
|
user, err := panel.dependencies.Auth.UserOfSession(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return sc, err
|
return sc, err
|
||||||
}
|
}
|
||||||
|
|
@ -66,7 +66,7 @@ func (panel *UserPanel) sshRoute(ctx context.Context) http.Handler {
|
||||||
sc.Port = panel.Config.Listen.SSHPort
|
sc.Port = panel.Config.Listen.SSHPort
|
||||||
|
|
||||||
// pick the first domain that the user has access to as an example
|
// pick the first domain that the user has access to as an example
|
||||||
grants, err := panel.Dependencies.Policy.User(r.Context(), user.User.User)
|
grants, err := panel.dependencies.Policy.User(r.Context(), user.User.User)
|
||||||
if err != nil && len(grants) > 0 {
|
if err != nil && len(grants) > 0 {
|
||||||
sc.Slug = grants[0].Slug
|
sc.Slug = grants[0].Slug
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -74,12 +74,12 @@ func (panel *UserPanel) sshRoute(ctx context.Context) http.Handler {
|
||||||
}
|
}
|
||||||
sc.Hostname = panel.Config.HTTP.HostFromSlug(sc.Slug)
|
sc.Hostname = panel.Config.HTTP.HostFromSlug(sc.Slug)
|
||||||
|
|
||||||
sc.Keys, err = panel.Dependencies.Keys.Keys(r.Context(), user.User.User)
|
sc.Keys, err = panel.dependencies.Keys.Keys(r.Context(), user.User.User)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return sc, err
|
return sc, err
|
||||||
}
|
}
|
||||||
|
|
||||||
sc.Services = panel.Dependencies.SSH2.Intercepts()
|
sc.Services = panel.dependencies.SSH2.Intercepts()
|
||||||
|
|
||||||
return sc, nil
|
return sc, nil
|
||||||
})
|
})
|
||||||
|
|
@ -100,7 +100,7 @@ func (panel *UserPanel) sshDeleteRoute(ctx context.Context) http.Handler {
|
||||||
httpx.HTMLInterceptor.Fallback.ServeHTTP(w, r)
|
httpx.HTMLInterceptor.Fallback.ServeHTTP(w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
user, err := panel.Dependencies.Auth.UserOfSession(r)
|
user, err := panel.dependencies.Auth.UserOfSession(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Err(err).Str("action", "delete ssh key").Msg("failed to get current user")
|
logger.Err(err).Str("action", "delete ssh key").Msg("failed to get current user")
|
||||||
httpx.HTMLInterceptor.Fallback.ServeHTTP(w, r)
|
httpx.HTMLInterceptor.Fallback.ServeHTTP(w, r)
|
||||||
|
|
@ -114,7 +114,7 @@ func (panel *UserPanel) sshDeleteRoute(ctx context.Context) http.Handler {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := panel.Dependencies.Keys.Remove(r.Context(), user.User.User, key); err != nil {
|
if err := panel.dependencies.Keys.Remove(r.Context(), user.User.User, key); err != nil {
|
||||||
logger.Err(err).Str("action", "delete ssh key").Msg("failed to delete key")
|
logger.Err(err).Str("action", "delete ssh key").Msg("failed to delete key")
|
||||||
httpx.HTMLInterceptor.Fallback.ServeHTTP(w, r)
|
httpx.HTMLInterceptor.Fallback.ServeHTTP(w, r)
|
||||||
return
|
return
|
||||||
|
|
@ -140,7 +140,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(
|
tpl := sshAddTemplate.Prepare(
|
||||||
panel.Dependencies.Templating,
|
panel.dependencies.Templating,
|
||||||
templating.Crumbs(
|
templating.Crumbs(
|
||||||
menuUser,
|
menuUser,
|
||||||
menuSSH,
|
menuSSH,
|
||||||
|
|
@ -159,7 +159,7 @@ func (panel *UserPanel) sshAddRoute(ctx context.Context) http.Handler {
|
||||||
RenderTemplateContext: templating.FormTemplateContext(tpl),
|
RenderTemplateContext: templating.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.UserOfSession(r)
|
ak.User, err = panel.dependencies.Auth.UserOfSession(r)
|
||||||
if err != nil || ak.User == nil {
|
if err != nil || ak.User == nil {
|
||||||
return ak, errInvalidUser
|
return ak, errInvalidUser
|
||||||
}
|
}
|
||||||
|
|
@ -181,7 +181,7 @@ func (panel *UserPanel) sshAddRoute(ctx context.Context) http.Handler {
|
||||||
|
|
||||||
RenderSuccess: func(ak addKeyResult, values map[string]string, w http.ResponseWriter, r *http.Request) error {
|
RenderSuccess: func(ak addKeyResult, values map[string]string, w http.ResponseWriter, r *http.Request) error {
|
||||||
// add the key to the user
|
// add the key to the user
|
||||||
if err := panel.Dependencies.Keys.Add(r.Context(), ak.User.User.User, ak.Comment, ak.Key); err != nil {
|
if err := panel.dependencies.Keys.Add(r.Context(), ak.User.User.User, ak.Comment, ak.Key); err != nil {
|
||||||
return errAddKey
|
return errAddKey
|
||||||
}
|
}
|
||||||
// everything went fine, redirect the user back to the user page!
|
// everything went fine, redirect the user back to the user page!
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ type TokenTemplateContext struct {
|
||||||
|
|
||||||
func (panel *UserPanel) tokensRoute(ctx context.Context) http.Handler {
|
func (panel *UserPanel) tokensRoute(ctx context.Context) http.Handler {
|
||||||
tpl := tokensTemplate.Prepare(
|
tpl := tokensTemplate.Prepare(
|
||||||
panel.Dependencies.Templating,
|
panel.dependencies.Templating,
|
||||||
templating.Crumbs(
|
templating.Crumbs(
|
||||||
menuUser,
|
menuUser,
|
||||||
menuTokens,
|
menuTokens,
|
||||||
|
|
@ -46,7 +46,7 @@ func (panel *UserPanel) tokensRoute(ctx context.Context) http.Handler {
|
||||||
|
|
||||||
return tpl.HTMLHandler(func(r *http.Request) (tc TokenTemplateContext, err error) {
|
return tpl.HTMLHandler(func(r *http.Request) (tc TokenTemplateContext, err error) {
|
||||||
// list the user
|
// list the user
|
||||||
user, err := panel.Dependencies.Auth.UserOfSession(r)
|
user, err := panel.dependencies.Auth.UserOfSession(r)
|
||||||
if err != nil || user == nil {
|
if err != nil || user == nil {
|
||||||
return tc, err
|
return tc, err
|
||||||
}
|
}
|
||||||
|
|
@ -54,7 +54,7 @@ func (panel *UserPanel) tokensRoute(ctx context.Context) http.Handler {
|
||||||
tc.Domain = template.URL(panel.Config.HTTP.JoinPath().String())
|
tc.Domain = template.URL(panel.Config.HTTP.JoinPath().String())
|
||||||
|
|
||||||
// get the tokens
|
// get the tokens
|
||||||
tc.Tokens, err = panel.Dependencies.Tokens.Tokens(r.Context(), user.User.User)
|
tc.Tokens, err = panel.dependencies.Tokens.Tokens(r.Context(), user.User.User)
|
||||||
return tc, err
|
return tc, err
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -67,7 +67,7 @@ func (panel *UserPanel) tokensDeleteRoute(ctx context.Context) http.Handler {
|
||||||
httpx.HTMLInterceptor.Fallback.ServeHTTP(w, r)
|
httpx.HTMLInterceptor.Fallback.ServeHTTP(w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
user, err := panel.Dependencies.Auth.UserOfSession(r)
|
user, err := panel.dependencies.Auth.UserOfSession(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Err(err).Str("action", "delete token").Msg("failed to get current user")
|
logger.Err(err).Str("action", "delete token").Msg("failed to get current user")
|
||||||
httpx.HTMLInterceptor.Fallback.ServeHTTP(w, r)
|
httpx.HTMLInterceptor.Fallback.ServeHTTP(w, r)
|
||||||
|
|
@ -81,7 +81,7 @@ func (panel *UserPanel) tokensDeleteRoute(ctx context.Context) http.Handler {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := panel.Dependencies.Tokens.Remove(r.Context(), user.User.User, id); err != nil {
|
if err := panel.dependencies.Tokens.Remove(r.Context(), user.User.User, id); err != nil {
|
||||||
logger.Err(err).Str("action", "delete token").Msg("failed to delete token")
|
logger.Err(err).Str("action", "delete token").Msg("failed to delete token")
|
||||||
httpx.HTMLInterceptor.Fallback.ServeHTTP(w, r)
|
httpx.HTMLInterceptor.Fallback.ServeHTTP(w, r)
|
||||||
return
|
return
|
||||||
|
|
@ -122,7 +122,7 @@ type TokenCreateContext struct {
|
||||||
|
|
||||||
func (panel *UserPanel) tokensAddRoute(ctx context.Context) http.Handler {
|
func (panel *UserPanel) tokensAddRoute(ctx context.Context) http.Handler {
|
||||||
tplForm := tokensAddTemplate.Prepare(
|
tplForm := tokensAddTemplate.Prepare(
|
||||||
panel.Dependencies.Templating,
|
panel.dependencies.Templating,
|
||||||
templating.Crumbs(
|
templating.Crumbs(
|
||||||
menuUser,
|
menuUser,
|
||||||
menuTokens,
|
menuTokens,
|
||||||
|
|
@ -131,7 +131,7 @@ func (panel *UserPanel) tokensAddRoute(ctx context.Context) http.Handler {
|
||||||
)
|
)
|
||||||
|
|
||||||
tplDone := tokenCreateTemplate.Prepare(
|
tplDone := tokenCreateTemplate.Prepare(
|
||||||
panel.Dependencies.Templating,
|
panel.dependencies.Templating,
|
||||||
templating.Crumbs(
|
templating.Crumbs(
|
||||||
menuUser,
|
menuUser,
|
||||||
menuTokens,
|
menuTokens,
|
||||||
|
|
@ -149,7 +149,7 @@ func (panel *UserPanel) tokensAddRoute(ctx context.Context) http.Handler {
|
||||||
RenderTemplateContext: templating.FormTemplateContext(tplForm),
|
RenderTemplateContext: templating.FormTemplateContext(tplForm),
|
||||||
|
|
||||||
Validate: func(r *http.Request, values map[string]string) (at addTokenResult, err error) {
|
Validate: func(r *http.Request, values map[string]string) (at addTokenResult, err error) {
|
||||||
at.User, err = panel.Dependencies.Auth.UserOfSession(r)
|
at.User, err = panel.dependencies.Auth.UserOfSession(r)
|
||||||
if err != nil || at.User == nil {
|
if err != nil || at.User == nil {
|
||||||
return at, errInvalidUser
|
return at, errInvalidUser
|
||||||
}
|
}
|
||||||
|
|
@ -166,7 +166,7 @@ func (panel *UserPanel) tokensAddRoute(ctx context.Context) http.Handler {
|
||||||
|
|
||||||
RenderSuccess: func(at addTokenResult, values map[string]string, w http.ResponseWriter, r *http.Request) error {
|
RenderSuccess: func(at addTokenResult, values map[string]string, w http.ResponseWriter, r *http.Request) error {
|
||||||
// add the key to the user
|
// add the key to the user
|
||||||
tok, err := panel.Dependencies.Tokens.Add(r.Context(), at.User.User.User, at.Description, at.Scopes)
|
tok, err := panel.dependencies.Tokens.Add(r.Context(), at.User.User.User, at.Description, at.Scopes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ var totpEnable = templating.Parse[userFormContext](
|
||||||
)
|
)
|
||||||
|
|
||||||
func (panel *UserPanel) routeTOTPEnable(ctx context.Context) http.Handler {
|
func (panel *UserPanel) routeTOTPEnable(ctx context.Context) http.Handler {
|
||||||
tpl := totpEnable.Prepare(panel.Dependencies.Templating)
|
tpl := totpEnable.Prepare(panel.dependencies.Templating)
|
||||||
|
|
||||||
return &httpx.Form[struct{}]{
|
return &httpx.Form[struct{}]{
|
||||||
Fields: []field.Field{
|
Fields: []field.Field{
|
||||||
|
|
@ -33,7 +33,7 @@ func (panel *UserPanel) routeTOTPEnable(ctx context.Context) http.Handler {
|
||||||
FieldTemplate: field.PureCSSFieldTemplate,
|
FieldTemplate: field.PureCSSFieldTemplate,
|
||||||
|
|
||||||
SkipForm: func(r *http.Request) (data struct{}, skip bool) {
|
SkipForm: func(r *http.Request) (data struct{}, skip bool) {
|
||||||
user, err := panel.Dependencies.Auth.UserOfSession(r)
|
user, err := panel.dependencies.Auth.UserOfSession(r)
|
||||||
return struct{}{}, err == nil && user != nil && user.IsTOTPEnabled()
|
return struct{}{}, err == nil && user != nil && user.IsTOTPEnabled()
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -43,7 +43,7 @@ func (panel *UserPanel) routeTOTPEnable(ctx context.Context) http.Handler {
|
||||||
Validate: func(r *http.Request, values map[string]string) (struct{}, error) {
|
Validate: func(r *http.Request, values map[string]string) (struct{}, error) {
|
||||||
password := values["password"]
|
password := values["password"]
|
||||||
|
|
||||||
user, err := panel.Dependencies.Auth.UserOfSession(r)
|
user, err := panel.dependencies.Auth.UserOfSession(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return struct{}{}, err
|
return struct{}{}, err
|
||||||
}
|
}
|
||||||
|
|
@ -90,7 +90,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(
|
tpl := totpEnrollTemplate.Prepare(
|
||||||
panel.Dependencies.Templating,
|
panel.dependencies.Templating,
|
||||||
templating.Crumbs(
|
templating.Crumbs(
|
||||||
menuUser,
|
menuUser,
|
||||||
menuTOTPEnable,
|
menuTOTPEnable,
|
||||||
|
|
@ -105,11 +105,11 @@ func (panel *UserPanel) routeTOTPEnroll(ctx context.Context) http.Handler {
|
||||||
FieldTemplate: field.PureCSSFieldTemplate,
|
FieldTemplate: field.PureCSSFieldTemplate,
|
||||||
|
|
||||||
SkipForm: func(r *http.Request) (data struct{}, skip bool) {
|
SkipForm: func(r *http.Request) (data struct{}, skip bool) {
|
||||||
user, err := panel.Dependencies.Auth.UserOfSession(r)
|
user, err := panel.dependencies.Auth.UserOfSession(r)
|
||||||
return struct{}{}, err == nil && user != nil && user.IsTOTPEnabled()
|
return struct{}{}, err == nil && user != nil && user.IsTOTPEnabled()
|
||||||
},
|
},
|
||||||
RenderTemplateContext: func(context httpx.FormContext, r *http.Request) any {
|
RenderTemplateContext: func(context httpx.FormContext, r *http.Request) any {
|
||||||
user, err := panel.Dependencies.Auth.UserOfSession(r)
|
user, err := panel.dependencies.Auth.UserOfSession(r)
|
||||||
|
|
||||||
ctx := totpEnrollContext{
|
ctx := totpEnrollContext{
|
||||||
userFormContext: userFormContext{
|
userFormContext: userFormContext{
|
||||||
|
|
@ -136,7 +136,7 @@ func (panel *UserPanel) routeTOTPEnroll(ctx context.Context) http.Handler {
|
||||||
Validate: func(r *http.Request, values map[string]string) (struct{}, error) {
|
Validate: func(r *http.Request, values map[string]string) (struct{}, error) {
|
||||||
password, otp := values["password"], values["otp"]
|
password, otp := values["password"], values["otp"]
|
||||||
|
|
||||||
user, err := panel.Dependencies.Auth.UserOfSession(r)
|
user, err := panel.dependencies.Auth.UserOfSession(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return struct{}{}, err
|
return struct{}{}, err
|
||||||
}
|
}
|
||||||
|
|
@ -174,7 +174,7 @@ var totpDisableTemplate = templating.Parse[userFormContext](
|
||||||
)
|
)
|
||||||
|
|
||||||
func (panel *UserPanel) routeTOTPDisable(ctx context.Context) http.Handler {
|
func (panel *UserPanel) routeTOTPDisable(ctx context.Context) http.Handler {
|
||||||
tpl := totpDisableTemplate.Prepare(panel.Dependencies.Templating)
|
tpl := totpDisableTemplate.Prepare(panel.dependencies.Templating)
|
||||||
|
|
||||||
return &httpx.Form[struct{}]{
|
return &httpx.Form[struct{}]{
|
||||||
Fields: []field.Field{
|
Fields: []field.Field{
|
||||||
|
|
@ -184,7 +184,7 @@ func (panel *UserPanel) routeTOTPDisable(ctx context.Context) http.Handler {
|
||||||
FieldTemplate: field.PureCSSFieldTemplate,
|
FieldTemplate: field.PureCSSFieldTemplate,
|
||||||
|
|
||||||
SkipForm: func(r *http.Request) (data struct{}, skip bool) {
|
SkipForm: func(r *http.Request) (data struct{}, skip bool) {
|
||||||
user, err := panel.Dependencies.Auth.UserOfSession(r)
|
user, err := panel.dependencies.Auth.UserOfSession(r)
|
||||||
return struct{}{}, err == nil && user != nil && !user.IsTOTPEnabled()
|
return struct{}{}, err == nil && user != nil && !user.IsTOTPEnabled()
|
||||||
},
|
},
|
||||||
RenderTemplate: tpl.Template(),
|
RenderTemplate: tpl.Template(),
|
||||||
|
|
@ -193,7 +193,7 @@ func (panel *UserPanel) routeTOTPDisable(ctx context.Context) http.Handler {
|
||||||
Validate: func(r *http.Request, values map[string]string) (struct{}, error) {
|
Validate: func(r *http.Request, values map[string]string) (struct{}, error) {
|
||||||
password, otp := values["password"], values["otp"]
|
password, otp := values["password"], values["otp"]
|
||||||
|
|
||||||
user, err := panel.Dependencies.Auth.UserOfSession(r)
|
user, err := panel.dependencies.Auth.UserOfSession(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return struct{}{}, err
|
return struct{}{}, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ func (panel *UserPanel) routeUser(ctx context.Context) http.Handler {
|
||||||
}
|
}
|
||||||
|
|
||||||
tpl := userTemplate.Prepare(
|
tpl := userTemplate.Prepare(
|
||||||
panel.Dependencies.Templating,
|
panel.dependencies.Templating,
|
||||||
templating.Crumbs(
|
templating.Crumbs(
|
||||||
menuUser,
|
menuUser,
|
||||||
),
|
),
|
||||||
|
|
@ -61,12 +61,12 @@ func (panel *UserPanel) routeUser(ctx context.Context) http.Handler {
|
||||||
|
|
||||||
return tpl.HTMLHandlerWithFlags(func(r *http.Request) (uc userContext, funcs []templating.FlagFunc, err error) {
|
return tpl.HTMLHandlerWithFlags(func(r *http.Request) (uc userContext, funcs []templating.FlagFunc, err error) {
|
||||||
// find the user
|
// find the user
|
||||||
uc.AuthUser, err = panel.Dependencies.Auth.UserOfSession(r)
|
uc.AuthUser, err = panel.dependencies.Auth.UserOfSession(r)
|
||||||
if err != nil || uc.AuthUser == nil {
|
if err != nil || uc.AuthUser == nil {
|
||||||
return uc, nil, err
|
return uc, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
uc.ShowAdminURLs = panel.Dependencies.Auth.CheckScope("", scopes.ScopeUserAdmin, r) == nil
|
uc.ShowAdminURLs = panel.dependencies.Auth.CheckScope("", scopes.ScopeUserAdmin, r) == nil
|
||||||
|
|
||||||
// replace the totp action in the menu
|
// replace the totp action in the menu
|
||||||
var totpAction component.MenuItem
|
var totpAction component.MenuItem
|
||||||
|
|
@ -81,7 +81,7 @@ func (panel *UserPanel) routeUser(ctx context.Context) http.Handler {
|
||||||
}
|
}
|
||||||
|
|
||||||
// find the grants
|
// find the grants
|
||||||
grants, err := panel.Dependencies.Policy.User(r.Context(), uc.AuthUser.User.User)
|
grants, err := panel.dependencies.Policy.User(r.Context(), uc.AuthUser.User.User)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return uc, nil, err
|
return uc, nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -90,7 +90,7 @@ func (panel *UserPanel) routeUser(ctx context.Context) http.Handler {
|
||||||
for i, grant := range grants {
|
for i, grant := range grants {
|
||||||
uc.Grants[i].Grant = grant
|
uc.Grants[i].Grant = grant
|
||||||
|
|
||||||
url, err := panel.Dependencies.Next.Next(r.Context(), grant.Slug, "/")
|
url, err := panel.dependencies.Next.Next(r.Context(), grant.Slug, "/")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return uc, nil, err
|
return uc, nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ func (policy *Policy) Set(ctx context.Context, grant models.Grant) error {
|
||||||
|
|
||||||
// check that the referenced user exists!
|
// check that the referenced user exists!
|
||||||
{
|
{
|
||||||
_, err := policy.Dependencies.Auth.User(ctx, grant.User)
|
_, err := policy.dependencies.Auth.User(ctx, grant.User)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ import (
|
||||||
type Policy struct {
|
type Policy struct {
|
||||||
component.Base
|
component.Base
|
||||||
|
|
||||||
Dependencies struct {
|
dependencies struct {
|
||||||
SQL *sql.SQL
|
SQL *sql.SQL
|
||||||
Auth *auth.Auth
|
Auth *auth.Auth
|
||||||
}
|
}
|
||||||
|
|
@ -29,10 +29,10 @@ var (
|
||||||
func (pol *Policy) TableInfo() component.TableInfo {
|
func (pol *Policy) TableInfo() component.TableInfo {
|
||||||
return component.TableInfo{
|
return component.TableInfo{
|
||||||
Name: models.GrantTable,
|
Name: models.GrantTable,
|
||||||
Model: reflectx.MakeType[models.Grant](),
|
Model: reflectx.TypeFor[models.Grant](),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pol *Policy) table(ctx context.Context) (*gorm.DB, error) {
|
func (pol *Policy) table(ctx context.Context) (*gorm.DB, error) {
|
||||||
return pol.Dependencies.SQL.QueryTable(ctx, pol)
|
return pol.dependencies.SQL.QueryTable(ctx, pol)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,8 +26,8 @@ func (auth *Auth) Scopes() map[component.Scope]component.ScopeInfo {
|
||||||
// getScopeMap return a (cached version of) all scopes
|
// getScopeMap return a (cached version of) all scopes
|
||||||
func (auth *Auth) getScopeMap() map[component.Scope]scopeMapEntry {
|
func (auth *Auth) getScopeMap() map[component.Scope]scopeMapEntry {
|
||||||
return auth.scopeMap.Get(func() map[component.Scope]scopeMapEntry {
|
return auth.scopeMap.Get(func() map[component.Scope]scopeMapEntry {
|
||||||
mp := make(map[component.Scope]scopeMapEntry, len(auth.Dependencies.ScopeProviders))
|
mp := make(map[component.Scope]scopeMapEntry, len(auth.dependencies.ScopeProviders))
|
||||||
for _, p := range auth.Dependencies.ScopeProviders {
|
for _, p := range auth.dependencies.ScopeProviders {
|
||||||
info := p.Scope()
|
info := p.Scope()
|
||||||
mp[info.Scope] = scopeMapEntry{
|
mp[info.Scope] = scopeMapEntry{
|
||||||
Provider: p,
|
Provider: p,
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ import (
|
||||||
|
|
||||||
type AdminLoggedIn struct {
|
type AdminLoggedIn struct {
|
||||||
component.Base
|
component.Base
|
||||||
Dependencies struct {
|
dependencies struct {
|
||||||
Auth *auth.Auth
|
Auth *auth.Auth
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -32,6 +32,6 @@ func (*AdminLoggedIn) Scope() component.ScopeInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (al *AdminLoggedIn) HasScope(param string, r *http.Request) (bool, error) {
|
func (al *AdminLoggedIn) HasScope(param string, r *http.Request) (bool, error) {
|
||||||
_, user, err := al.Dependencies.Auth.SessionOf(r)
|
_, user, err := al.dependencies.Auth.SessionOf(r)
|
||||||
return user != nil && user.IsAdmin() && user.IsTOTPEnabled(), err
|
return user != nil && user.IsAdmin() && user.IsTOTPEnabled(), err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ import (
|
||||||
|
|
||||||
type ListInstancesScope struct {
|
type ListInstancesScope struct {
|
||||||
component.Base
|
component.Base
|
||||||
Dependencies struct {
|
dependencies struct {
|
||||||
Auth *auth.Auth
|
Auth *auth.Auth
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -32,6 +32,6 @@ func (*ListInstancesScope) Scope() component.ScopeInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lis *ListInstancesScope) HasScope(param string, r *http.Request) (bool, error) {
|
func (lis *ListInstancesScope) HasScope(param string, r *http.Request) (bool, error) {
|
||||||
_, user, err := lis.Dependencies.Auth.SessionOf(r)
|
_, user, err := lis.dependencies.Auth.SessionOf(r)
|
||||||
return user != nil, err
|
return user != nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ import (
|
||||||
|
|
||||||
type Never struct {
|
type Never struct {
|
||||||
component.Base
|
component.Base
|
||||||
Dependencies struct {
|
dependencies struct {
|
||||||
Auth *auth.Auth
|
Auth *auth.Auth
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ import (
|
||||||
|
|
||||||
type ListNewsScope struct {
|
type ListNewsScope struct {
|
||||||
component.Base
|
component.Base
|
||||||
Dependencies struct {
|
dependencies struct {
|
||||||
Auth *auth.Auth
|
Auth *auth.Auth
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -32,6 +32,6 @@ func (*ListNewsScope) Scope() component.ScopeInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lns *ListNewsScope) HasScope(param string, r *http.Request) (bool, error) {
|
func (lns *ListNewsScope) HasScope(param string, r *http.Request) (bool, error) {
|
||||||
_, user, err := lns.Dependencies.Auth.SessionOf(r)
|
_, user, err := lns.dependencies.Auth.SessionOf(r)
|
||||||
return user != nil, err
|
return user != nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ import (
|
||||||
|
|
||||||
type ResolverScope struct {
|
type ResolverScope struct {
|
||||||
component.Base
|
component.Base
|
||||||
Dependencies struct {
|
dependencies struct {
|
||||||
Auth *auth.Auth
|
Auth *auth.Auth
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -32,6 +32,6 @@ func (*ResolverScope) Scope() component.ScopeInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rs *ResolverScope) HasScope(param string, r *http.Request) (bool, error) {
|
func (rs *ResolverScope) HasScope(param string, r *http.Request) (bool, error) {
|
||||||
_, user, err := rs.Dependencies.Auth.SessionOf(r)
|
_, user, err := rs.dependencies.Auth.SessionOf(r)
|
||||||
return user != nil, err
|
return user != nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ import (
|
||||||
|
|
||||||
type UserLoggedIn struct {
|
type UserLoggedIn struct {
|
||||||
component.Base
|
component.Base
|
||||||
Dependencies struct {
|
dependencies struct {
|
||||||
Auth *auth.Auth
|
Auth *auth.Auth
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -31,6 +31,6 @@ func (*UserLoggedIn) Scope() component.ScopeInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (iu *UserLoggedIn) HasScope(param string, r *http.Request) (bool, error) {
|
func (iu *UserLoggedIn) HasScope(param string, r *http.Request) (bool, error) {
|
||||||
_, user, err := iu.Dependencies.Auth.SessionOf(r)
|
_, user, err := iu.dependencies.Auth.SessionOf(r)
|
||||||
return user != nil, err
|
return user != nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ func (auth *Auth) SessionOf(r *http.Request) (session component.SessionInfo, use
|
||||||
// To check the user of a token or session, use SessionOf.
|
// To check the user of a token or session, use SessionOf.
|
||||||
func (auth *Auth) UserOfToken(r *http.Request) (user *AuthUser, err error) {
|
func (auth *Auth) UserOfToken(r *http.Request) (user *AuthUser, err error) {
|
||||||
// get the token object
|
// get the token object
|
||||||
token, err := auth.Dependencies.Tokens.TokenOf(r)
|
token, err := auth.dependencies.Tokens.TokenOf(r)
|
||||||
if token == nil {
|
if token == nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -173,7 +173,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(
|
tpl := loginTemplate.Prepare(
|
||||||
auth.Dependencies.Templating,
|
auth.dependencies.Templating,
|
||||||
func(flags templating.Flags, r *http.Request) templating.Flags {
|
func(flags templating.Flags, r *http.Request) templating.Flags {
|
||||||
flags.Crumbs = []component.MenuItem{
|
flags.Crumbs = []component.MenuItem{
|
||||||
{Title: "Login", Path: template.URL(r.URL.RequestURI())},
|
{Title: "Login", Path: template.URL(r.URL.RequestURI())},
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ import (
|
||||||
type Tokens struct {
|
type Tokens struct {
|
||||||
component.Base
|
component.Base
|
||||||
|
|
||||||
Dependencies struct {
|
dependencies struct {
|
||||||
SQL *sql.SQL
|
SQL *sql.SQL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -30,12 +30,12 @@ var (
|
||||||
func (tok *Tokens) TableInfo() component.TableInfo {
|
func (tok *Tokens) TableInfo() component.TableInfo {
|
||||||
return component.TableInfo{
|
return component.TableInfo{
|
||||||
Name: models.TokensTable,
|
Name: models.TokensTable,
|
||||||
Model: reflectx.MakeType[models.Token](),
|
Model: reflectx.TypeFor[models.Token](),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tok *Tokens) table(ctx context.Context) (*gorm.DB, error) {
|
func (tok *Tokens) table(ctx context.Context) (*gorm.DB, error) {
|
||||||
return tok.Dependencies.SQL.QueryTable(ctx, tok)
|
return tok.dependencies.SQL.QueryTable(ctx, tok)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tok *Tokens) OnUserDelete(ctx context.Context, user *models.User) error {
|
func (tok *Tokens) OnUserDelete(ctx context.Context, user *models.User) error {
|
||||||
|
|
|
||||||
|
|
@ -25,14 +25,14 @@ var ErrUserNotFound = errors.New("user not found")
|
||||||
func (auth *Auth) TableInfo() component.TableInfo {
|
func (auth *Auth) TableInfo() component.TableInfo {
|
||||||
return component.TableInfo{
|
return component.TableInfo{
|
||||||
Name: models.UserTable,
|
Name: models.UserTable,
|
||||||
Model: reflectx.MakeType[models.User](),
|
Model: reflectx.TypeFor[models.User](),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Users returns all users in the database
|
// Users returns all users in the database
|
||||||
func (auth *Auth) Users(ctx context.Context) (users []*AuthUser, err error) {
|
func (auth *Auth) Users(ctx context.Context) (users []*AuthUser, err error) {
|
||||||
// query the user table
|
// query the user table
|
||||||
table, err := auth.Dependencies.SQL.QueryTable(ctx, auth)
|
table, err := auth.dependencies.SQL.QueryTable(ctx, auth)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -65,7 +65,7 @@ func (auth *Auth) User(ctx context.Context, name string) (user *AuthUser, err er
|
||||||
}
|
}
|
||||||
|
|
||||||
// return the user
|
// return the user
|
||||||
table, err := auth.Dependencies.SQL.QueryTable(ctx, auth)
|
table, err := auth.dependencies.SQL.QueryTable(ctx, auth)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -96,7 +96,7 @@ func (auth *Auth) User(ctx context.Context, name string) (user *AuthUser, err er
|
||||||
// The user is not associated to any WissKIs, and has no password set.
|
// The user is not associated to any WissKIs, and has no password set.
|
||||||
func (auth *Auth) CreateUser(ctx context.Context, name string) (user *AuthUser, err error) {
|
func (auth *Auth) CreateUser(ctx context.Context, name string) (user *AuthUser, err error) {
|
||||||
// return the user
|
// return the user
|
||||||
table, err := auth.Dependencies.SQL.QueryTable(ctx, auth)
|
table, err := auth.dependencies.SQL.QueryTable(ctx, auth)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -323,7 +323,7 @@ func (au *AuthUser) MakeRegular(ctx context.Context) error {
|
||||||
|
|
||||||
// Save saves the given user in the database
|
// Save saves the given user in the database
|
||||||
func (au *AuthUser) Save(ctx context.Context) error {
|
func (au *AuthUser) Save(ctx context.Context) error {
|
||||||
table, err := au.auth.Dependencies.SQL.QueryTable(ctx, au.auth)
|
table, err := au.auth.dependencies.SQL.QueryTable(ctx, au.auth)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -332,13 +332,13 @@ func (au *AuthUser) Save(ctx context.Context) error {
|
||||||
|
|
||||||
// Delete deletes the user from the database
|
// Delete deletes the user from the database
|
||||||
func (au *AuthUser) Delete(ctx context.Context) error {
|
func (au *AuthUser) Delete(ctx context.Context) error {
|
||||||
table, err := au.auth.Dependencies.SQL.QueryTable(ctx, au.auth)
|
table, err := au.auth.dependencies.SQL.QueryTable(ctx, au.auth)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// run all the user delete hooks
|
// run all the user delete hooks
|
||||||
for _, c := range au.auth.Dependencies.UserDeleteHooks {
|
for _, c := range au.auth.dependencies.UserDeleteHooks {
|
||||||
if err := c.OnUserDelete(ctx, &au.User); err != nil {
|
if err := c.OnUserDelete(ctx, &au.User); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,15 +43,13 @@ func (cb *Base) getBase() *Base {
|
||||||
|
|
||||||
// Init initialzes a new componeont Component with the provided still.
|
// Init initialzes a new componeont Component with the provided still.
|
||||||
// Init is only initended to be used within a lifetime.Lifetime[Component,Still].
|
// Init is only initended to be used within a lifetime.Lifetime[Component,Still].
|
||||||
func Init(component Component, core Still) Component {
|
func Init(component Component, core Still) {
|
||||||
base := component.getBase() // pointer to a struct
|
base := component.getBase() // pointer to a struct
|
||||||
base.Still = core
|
base.Still = core
|
||||||
|
|
||||||
tp := reflect.TypeOf(component).Elem()
|
tp := reflect.TypeOf(component).Elem()
|
||||||
base.name = strings.ToLower(tp.Name())
|
base.name = strings.ToLower(tp.Name())
|
||||||
base.id = tp.PkgPath() + "." + tp.Name()
|
base.id = tp.PkgPath() + "." + tp.Name()
|
||||||
|
|
||||||
return component
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cb Base) Name() string {
|
func (cb Base) Name() string {
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
||||||
|
|
@ -75,7 +76,7 @@ func (backup *Backup) run(ctx context.Context, progress io.Writer, exporter *Exp
|
||||||
defer done()
|
defer done()
|
||||||
|
|
||||||
// create a new status display
|
// create a new status display
|
||||||
backups := exporter.Dependencies.Backupable
|
backups := exporter.dependencies.Backupable
|
||||||
backup.ComponentErrors = make(map[string]error, len(backups))
|
backup.ComponentErrors = make(map[string]error, len(backups))
|
||||||
|
|
||||||
// Component backup tasks
|
// Component backup tasks
|
||||||
|
|
@ -124,7 +125,7 @@ func (backup *Backup) run(ctx context.Context, progress io.Writer, exporter *Exp
|
||||||
}
|
}
|
||||||
|
|
||||||
// list all instances
|
// list all instances
|
||||||
wissKIs, err := exporter.Dependencies.Instances.All(ctx)
|
wissKIs, err := exporter.dependencies.Instances.All(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
backup.InstanceListErr = err
|
backup.InstanceListErr = err
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -159,8 +160,8 @@ func (backup *Backup) run(ctx context.Context, progress io.Writer, exporter *Exp
|
||||||
}.Use(st, wissKIs)
|
}.Use(st, wissKIs)
|
||||||
|
|
||||||
// sort the instances
|
// sort the instances
|
||||||
slices.SortFunc(backup.InstanceSnapshots, func(a, b Snapshot) bool {
|
slices.SortFunc(backup.InstanceSnapshots, func(a, b Snapshot) int {
|
||||||
return a.Instance.Slug < b.Instance.Slug
|
return strings.Compare(a.Instance.Slug, b.Instance.Slug)
|
||||||
})
|
})
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ import (
|
||||||
// Exporter manages snapshots and backups
|
// Exporter manages snapshots and backups
|
||||||
type Exporter struct {
|
type Exporter struct {
|
||||||
component.Base
|
component.Base
|
||||||
Dependencies struct {
|
dependencies struct {
|
||||||
SQL *sql.SQL
|
SQL *sql.SQL
|
||||||
Instances *instances.Instances
|
Instances *instances.Instances
|
||||||
ExporterLogger *logger.Logger
|
ExporterLogger *logger.Logger
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import (
|
||||||
|
|
||||||
type Pathbuilders struct {
|
type Pathbuilders struct {
|
||||||
component.Base
|
component.Base
|
||||||
Dependencies struct {
|
dependencies struct {
|
||||||
Instances *instances.Instances
|
Instances *instances.Instances
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -26,7 +26,7 @@ func (Pathbuilders) SnapshotName() string { return "pathbuilders" }
|
||||||
|
|
||||||
func (pbs *Pathbuilders) Snapshot(wisski models.Instance, scontext *component.StagingContext) error {
|
func (pbs *Pathbuilders) Snapshot(wisski models.Instance, scontext *component.StagingContext) error {
|
||||||
return scontext.AddDirectory(".", func(ctx context.Context) error {
|
return scontext.AddDirectory(".", func(ctx context.Context) error {
|
||||||
builders, err := pbs.Dependencies.Instances.Instance(ctx, wisski).Pathbuilder().GetAll(ctx, nil)
|
builders, err := pbs.dependencies.Instances.Instance(ctx, wisski).Pathbuilder().GetAll(ctx, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ type export interface {
|
||||||
|
|
||||||
// Parts lists all available snapshot parts
|
// Parts lists all available snapshot parts
|
||||||
func (exporter *Exporter) Parts() []string {
|
func (exporter *Exporter) Parts() []string {
|
||||||
return collection.MapSlice(exporter.Dependencies.Snapshotable, func(c component.Snapshotable) string { return c.SnapshotName() })
|
return collection.MapSlice(exporter.dependencies.Snapshotable, func(c component.Snapshotable) string { return c.SnapshotName() })
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
@ -172,7 +172,7 @@ func (exporter *Exporter) MakeExport(ctx context.Context, progress io.Writer, ta
|
||||||
// write out the log entry
|
// write out the log entry
|
||||||
entry.Path = stagingDir
|
entry.Path = stagingDir
|
||||||
entry.Packed = false
|
entry.Packed = false
|
||||||
exporter.Dependencies.ExporterLogger.Add(ctx, entry)
|
exporter.dependencies.ExporterLogger.Add(ctx, entry)
|
||||||
|
|
||||||
fmt.Fprintf(progress, "Wrote %s\n", stagingDir)
|
fmt.Fprintf(progress, "Wrote %s\n", stagingDir)
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -200,7 +200,7 @@ func (exporter *Exporter) MakeExport(ctx context.Context, progress io.Writer, ta
|
||||||
logging.LogMessage(progress, "Writing Log Entry")
|
logging.LogMessage(progress, "Writing Log Entry")
|
||||||
entry.Path = archivePath
|
entry.Path = archivePath
|
||||||
entry.Packed = true
|
entry.Packed = true
|
||||||
exporter.Dependencies.ExporterLogger.Add(ctx, entry)
|
exporter.dependencies.ExporterLogger.Add(ctx, entry)
|
||||||
|
|
||||||
// and we're done!
|
// and we're done!
|
||||||
return nil
|
return nil
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ import (
|
||||||
// Logger is responsible for logging backups and snapshots
|
// Logger is responsible for logging backups and snapshots
|
||||||
type Logger struct {
|
type Logger struct {
|
||||||
component.Base
|
component.Base
|
||||||
Dependencies struct {
|
dependencies struct {
|
||||||
SQL *sql.SQL
|
SQL *sql.SQL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -28,7 +28,7 @@ var (
|
||||||
|
|
||||||
func (*Logger) TableInfo() component.TableInfo {
|
func (*Logger) TableInfo() component.TableInfo {
|
||||||
return component.TableInfo{
|
return component.TableInfo{
|
||||||
Model: reflectx.MakeType[models.Export](),
|
Model: reflectx.TypeFor[models.Export](),
|
||||||
Name: models.ExportTable,
|
Name: models.ExportTable,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -50,7 +50,7 @@ func (log *Logger) For(ctx context.Context, slug string) (exports []models.Expor
|
||||||
// Log retrieves (and prunes) all entries in the snapshot log.
|
// Log retrieves (and prunes) all entries in the snapshot log.
|
||||||
func (log *Logger) Log(ctx context.Context) ([]models.Export, error) {
|
func (log *Logger) Log(ctx context.Context) ([]models.Export, error) {
|
||||||
// query the table!
|
// query the table!
|
||||||
table, err := log.Dependencies.SQL.QueryTable(ctx, log)
|
table, err := log.dependencies.SQL.QueryTable(ctx, log)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -82,7 +82,7 @@ func (log *Logger) Log(ctx context.Context) ([]models.Export, error) {
|
||||||
// AddToExportLog adds the provided export to the log.
|
// AddToExportLog adds the provided export to the log.
|
||||||
func (log *Logger) Add(ctx context.Context, export models.Export) error {
|
func (log *Logger) Add(ctx context.Context, export models.Export) error {
|
||||||
// find the table
|
// find the table
|
||||||
table, err := log.Dependencies.SQL.QueryTable(ctx, log)
|
table, err := log.dependencies.SQL.QueryTable(ctx, log)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,6 @@ func (exporter *Exporter) PruneExports(ctx context.Context, progress io.Writer)
|
||||||
}
|
}
|
||||||
|
|
||||||
// prune the snapshot log!
|
// prune the snapshot log!
|
||||||
_, err = exporter.Dependencies.ExporterLogger.Log(ctx)
|
_, err = exporter.dependencies.ExporterLogger.Log(ctx)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -113,8 +113,8 @@ func (exporter *Exporter) NewSnapshot(ctx context.Context, instance *wisski.Wiss
|
||||||
// Also sets up snapshot.partsRunning and snapshot.partsStopped.
|
// Also sets up snapshot.partsRunning and snapshot.partsStopped.
|
||||||
// sends a warning about unknown parts into the logger in context.
|
// sends a warning about unknown parts into the logger in context.
|
||||||
func (snapshots *Exporter) resolveParts(ctx context.Context, parts []string, snapshot *Snapshot) {
|
func (snapshots *Exporter) resolveParts(ctx context.Context, parts []string, snapshot *Snapshot) {
|
||||||
partMap := make(map[string]component.Snapshotable, len(snapshots.Dependencies.Snapshotable))
|
partMap := make(map[string]component.Snapshotable, len(snapshots.dependencies.Snapshotable))
|
||||||
for _, part := range snapshots.Dependencies.Snapshotable {
|
for _, part := range snapshots.dependencies.Snapshotable {
|
||||||
partMap[part.SnapshotName()] = part
|
partMap[part.SnapshotName()] = part
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ import (
|
||||||
// Instances manages multiple WissKI Instances.
|
// Instances manages multiple WissKI Instances.
|
||||||
type Instances struct {
|
type Instances struct {
|
||||||
component.Base
|
component.Base
|
||||||
Dependencies struct {
|
dependencies struct {
|
||||||
Malt *malt.Malt
|
Malt *malt.Malt
|
||||||
SQL *sql.SQL
|
SQL *sql.SQL
|
||||||
|
|
||||||
|
|
@ -41,7 +41,7 @@ var errSQL = exit.Error{
|
||||||
|
|
||||||
// use uses the non-nil wisski instance with this instances
|
// use uses the non-nil wisski instance with this instances
|
||||||
func (instances *Instances) use(wisski *wisski.WissKI) {
|
func (instances *Instances) use(wisski *wisski.WissKI) {
|
||||||
wisski.Liquid.Malt = instances.Dependencies.Malt
|
wisski.Liquid.Malt = instances.dependencies.Malt
|
||||||
}
|
}
|
||||||
|
|
||||||
// WissKI returns the WissKI with the provided slug, if it exists.
|
// WissKI returns the WissKI with the provided slug, if it exists.
|
||||||
|
|
@ -51,12 +51,12 @@ func (instances *Instances) WissKI(ctx context.Context, slug string) (wissKI *wi
|
||||||
return nil, ErrWissKINotFound
|
return nil, ErrWissKINotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
sql := instances.Dependencies.SQL
|
sql := instances.dependencies.SQL
|
||||||
if err := sql.WaitQueryTable(ctx); err != nil {
|
if err := sql.WaitQueryTable(ctx); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
table, err := sql.QueryTable(ctx, instances.Dependencies.InstanceTable)
|
table, err := sql.QueryTable(ctx, instances.dependencies.InstanceTable)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -91,12 +91,12 @@ func (instances *Instances) Instance(ctx context.Context, instance models.Instan
|
||||||
// Has checks if a WissKI with the provided slug exists inside the database.
|
// Has checks if a WissKI with the provided slug exists inside the database.
|
||||||
// It does not perform any checks on the WissKI itself.
|
// It does not perform any checks on the WissKI itself.
|
||||||
func (instances *Instances) Has(ctx context.Context, slug string) (ok bool, err error) {
|
func (instances *Instances) Has(ctx context.Context, slug string) (ok bool, err error) {
|
||||||
sql := instances.Dependencies.SQL
|
sql := instances.dependencies.SQL
|
||||||
if err := sql.WaitQueryTable(ctx); err != nil {
|
if err := sql.WaitQueryTable(ctx); err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
table, err := sql.QueryTable(ctx, instances.Dependencies.InstanceTable)
|
table, err := sql.QueryTable(ctx, instances.dependencies.InstanceTable)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
@ -135,13 +135,13 @@ func (instances *Instances) Load(ctx context.Context, slugs ...string) ([]*wissk
|
||||||
|
|
||||||
// find finds instances based on the provided query
|
// find finds instances based on the provided query
|
||||||
func (instances *Instances) find(ctx context.Context, order bool, query func(table *gorm.DB) *gorm.DB) (results []*wisski.WissKI, err error) {
|
func (instances *Instances) find(ctx context.Context, order bool, query func(table *gorm.DB) *gorm.DB) (results []*wisski.WissKI, err error) {
|
||||||
sql := instances.Dependencies.SQL
|
sql := instances.dependencies.SQL
|
||||||
if err := sql.WaitQueryTable(ctx); err != nil {
|
if err := sql.WaitQueryTable(ctx); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// open the bookkeeping table
|
// open the bookkeeping table
|
||||||
table, err := sql.QueryTable(ctx, instances.Dependencies.InstanceTable)
|
table, err := sql.QueryTable(ctx, instances.dependencies.InstanceTable)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,16 +15,16 @@ import (
|
||||||
type Malt struct {
|
type Malt struct {
|
||||||
component.Base
|
component.Base
|
||||||
|
|
||||||
SQL *sql.SQL `auto:"true"`
|
SQL *sql.SQL `inject:"true"`
|
||||||
InstanceTable *sql.InstanceTable `auto:"true"`
|
InstanceTable *sql.InstanceTable `inject:"true"`
|
||||||
LockTable *sql.LockTable `auto:"true"`
|
LockTable *sql.LockTable `inject:"true"`
|
||||||
|
|
||||||
TS *triplestore.Triplestore `auto:"true"`
|
TS *triplestore.Triplestore `inject:"true"`
|
||||||
Meta *meta.Meta `auto:"true"`
|
Meta *meta.Meta `inject:"true"`
|
||||||
ExporterLog *logger.Logger `auto:"true"`
|
ExporterLog *logger.Logger `inject:"true"`
|
||||||
Policy *policy.Policy `auto:"true"`
|
Policy *policy.Policy `inject:"true"`
|
||||||
|
|
||||||
Docker *docker.Docker `auto:"true"`
|
Docker *docker.Docker `inject:"true"`
|
||||||
|
|
||||||
Keys *sshkeys.SSHKeys `auto:"true"`
|
Keys *sshkeys.SSHKeys `inject:"true"`
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ import (
|
||||||
// Purger purges instances from the distillery
|
// Purger purges instances from the distillery
|
||||||
type Purger struct {
|
type Purger struct {
|
||||||
component.Base
|
component.Base
|
||||||
Dependencies struct {
|
dependencies struct {
|
||||||
Instances *instances.Instances
|
Instances *instances.Instances
|
||||||
Provisionable []component.Provisionable
|
Provisionable []component.Provisionable
|
||||||
}
|
}
|
||||||
|
|
@ -35,10 +35,10 @@ var errPurgeGeneric = exit.Error{
|
||||||
// The instance does not have to exist; in which case the resources are also deleted.
|
// The instance does not have to exist; in which case the resources are also deleted.
|
||||||
func (purger *Purger) Purge(ctx context.Context, out io.Writer, slug string) error {
|
func (purger *Purger) Purge(ctx context.Context, out io.Writer, slug string) error {
|
||||||
logging.LogMessage(out, "Checking bookkeeping table")
|
logging.LogMessage(out, "Checking bookkeeping table")
|
||||||
instance, err := purger.Dependencies.Instances.WissKI(ctx, slug)
|
instance, err := purger.dependencies.Instances.WissKI(ctx, slug)
|
||||||
if err == instances.ErrWissKINotFound {
|
if err == instances.ErrWissKINotFound {
|
||||||
fmt.Fprintln(out, "Not found in bookkeeping table, assuming defaults")
|
fmt.Fprintln(out, "Not found in bookkeeping table, assuming defaults")
|
||||||
instance, err = purger.Dependencies.Instances.Create(slug, models.System{})
|
instance, err = purger.dependencies.Instances.Create(slug, models.System{})
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errPurgeNoDetails.WithMessageF(err)
|
return errPurgeNoDetails.WithMessageF(err)
|
||||||
|
|
@ -59,7 +59,7 @@ func (purger *Purger) Purge(ctx context.Context, out io.Writer, slug string) err
|
||||||
// purge all the instance specific resources
|
// purge all the instance specific resources
|
||||||
if err := logging.LogOperation(func() error {
|
if err := logging.LogOperation(func() error {
|
||||||
domain := instance.Domain()
|
domain := instance.Domain()
|
||||||
for _, pc := range purger.Dependencies.Provisionable {
|
for _, pc := range purger.dependencies.Provisionable {
|
||||||
logging.LogMessage(out, "Purging %s resources", pc.Name())
|
logging.LogMessage(out, "Purging %s resources", pc.Name())
|
||||||
err := pc.Purge(ctx, instance.Instance, domain)
|
err := pc.Purge(ctx, instance.Instance, domain)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -48,8 +48,8 @@ func (mi MenuItem) ReplaceWith(new MenuItem, items []MenuItem) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func MenuItemSort(a, b MenuItem) bool {
|
func MenuItemSort(a, b MenuItem) int {
|
||||||
return a.Priority < b.Priority
|
return int(a.Priority) - int(b.Priority)
|
||||||
}
|
}
|
||||||
|
|
||||||
type MenuPriority int
|
type MenuPriority int
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ import (
|
||||||
// Component meta is responsible for managing metadata per WissKI Instance
|
// Component meta is responsible for managing metadata per WissKI Instance
|
||||||
type Meta struct {
|
type Meta struct {
|
||||||
component.Base
|
component.Base
|
||||||
Dependencies struct {
|
dependencies struct {
|
||||||
SQL *sql.SQL
|
SQL *sql.SQL
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -27,7 +27,7 @@ var (
|
||||||
|
|
||||||
func (*Meta) TableInfo() component.TableInfo {
|
func (*Meta) TableInfo() component.TableInfo {
|
||||||
return component.TableInfo{
|
return component.TableInfo{
|
||||||
Model: reflectx.MakeType[models.Metadatum](),
|
Model: reflectx.TypeFor[models.Metadatum](),
|
||||||
Name: models.MetadataTable,
|
Name: models.MetadataTable,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -51,7 +51,7 @@ func (meta *Meta) Storage(slug string) *Storage {
|
||||||
// create a new storage
|
// create a new storage
|
||||||
meta.sc[slug] = &Storage{
|
meta.sc[slug] = &Storage{
|
||||||
Slug: slug,
|
Slug: slug,
|
||||||
sql: meta.Dependencies.SQL,
|
sql: meta.dependencies.SQL,
|
||||||
table: meta,
|
table: meta,
|
||||||
}
|
}
|
||||||
return meta.sc[slug]
|
return meta.sc[slug]
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ import (
|
||||||
|
|
||||||
type Provision struct {
|
type Provision struct {
|
||||||
component.Base
|
component.Base
|
||||||
Dependencies struct {
|
dependencies struct {
|
||||||
Instances *instances.Instances
|
Instances *instances.Instances
|
||||||
Provisionable []component.Provisionable
|
Provisionable []component.Provisionable
|
||||||
}
|
}
|
||||||
|
|
@ -44,7 +44,7 @@ var ErrInstanceAlreadyExists = errors.New("instance with provided slug already e
|
||||||
|
|
||||||
func (pv *Provision) Validate(flags Flags) error {
|
func (pv *Provision) Validate(flags Flags) error {
|
||||||
// check the slug
|
// check the slug
|
||||||
if _, err := pv.Dependencies.Instances.IsValidSlug(flags.Slug); err != nil {
|
if _, err := pv.dependencies.Instances.IsValidSlug(flags.Slug); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -54,7 +54,7 @@ func (pv *Provision) Validate(flags Flags) error {
|
||||||
func (pv *Provision) Provision(progress io.Writer, ctx context.Context, flags Flags) (*wisski.WissKI, error) {
|
func (pv *Provision) Provision(progress io.Writer, ctx context.Context, flags Flags) (*wisski.WissKI, error) {
|
||||||
// check that it doesn't already exist
|
// check that it doesn't already exist
|
||||||
logging.LogMessage(progress, "Provisioning new WissKI instance %s", flags.Slug)
|
logging.LogMessage(progress, "Provisioning new WissKI instance %s", flags.Slug)
|
||||||
if exists, err := pv.Dependencies.Instances.Has(ctx, flags.Slug); err != nil || exists {
|
if exists, err := pv.dependencies.Instances.Has(ctx, flags.Slug); err != nil || exists {
|
||||||
return nil, ErrInstanceAlreadyExists
|
return nil, ErrInstanceAlreadyExists
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -62,7 +62,7 @@ func (pv *Provision) Provision(progress io.Writer, ctx context.Context, flags Fl
|
||||||
fmt.Fprintf(progress, "%#v", flags)
|
fmt.Fprintf(progress, "%#v", flags)
|
||||||
|
|
||||||
// make it in-memory
|
// make it in-memory
|
||||||
instance, err := pv.Dependencies.Instances.Create(flags.Slug, flags.System)
|
instance, err := pv.dependencies.Instances.Create(flags.Slug, flags.System)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -93,7 +93,7 @@ func (pv *Provision) Provision(progress io.Writer, ctx context.Context, flags Fl
|
||||||
// create all the resources!
|
// create all the resources!
|
||||||
if err := logging.LogOperation(func() error {
|
if err := logging.LogOperation(func() error {
|
||||||
domain := instance.Domain()
|
domain := instance.Domain()
|
||||||
for _, pc := range pv.Dependencies.Provisionable {
|
for _, pc := range pv.dependencies.Provisionable {
|
||||||
logging.LogMessage(progress, "Provisioning %s resources", pc.Name())
|
logging.LogMessage(progress, "Provisioning %s resources", pc.Name())
|
||||||
err := pc.Provision(ctx, instance.Instance, domain)
|
err := pc.Provision(ctx, instance.Instance, domain)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ import (
|
||||||
|
|
||||||
type API struct {
|
type API struct {
|
||||||
component.Base
|
component.Base
|
||||||
Dependencies struct {
|
dependencies struct {
|
||||||
Auth *auth.Auth
|
Auth *auth.Auth
|
||||||
Resolver *Resolver
|
Resolver *Resolver
|
||||||
}
|
}
|
||||||
|
|
@ -33,7 +33,7 @@ func (api *API) Routes() component.Routes {
|
||||||
func (a *API) HandleRoute(ctx context.Context, path string) (http.Handler, error) {
|
func (a *API) HandleRoute(ctx context.Context, path string) (http.Handler, error) {
|
||||||
return &api.Handler[string]{
|
return &api.Handler[string]{
|
||||||
Config: a.Config,
|
Config: a.Config,
|
||||||
Auth: a.Dependencies.Auth,
|
Auth: a.dependencies.Auth,
|
||||||
|
|
||||||
Methods: []string{"GET"},
|
Methods: []string{"GET"},
|
||||||
|
|
||||||
|
|
@ -43,7 +43,7 @@ func (a *API) HandleRoute(ctx context.Context, path string) (http.Handler, error
|
||||||
if uri == "" {
|
if uri == "" {
|
||||||
return "", httpx.ErrBadRequest
|
return "", httpx.ErrBadRequest
|
||||||
}
|
}
|
||||||
target := a.Dependencies.Resolver.Target(uri)
|
target := a.dependencies.Resolver.Target(uri)
|
||||||
if target == "" {
|
if target == "" {
|
||||||
return "", httpx.ErrNotFound
|
return "", httpx.ErrNotFound
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ func (resolver *Resolver) Cron(ctx context.Context) error {
|
||||||
// AllPrefixes returns a list of all prefixes from the server.
|
// AllPrefixes returns a list of all prefixes from the server.
|
||||||
// Prefixes may be cached on the server
|
// Prefixes may be cached on the server
|
||||||
func (resolver *Resolver) AllPrefixes(ctx context.Context) (map[string]string, error) {
|
func (resolver *Resolver) AllPrefixes(ctx context.Context) (map[string]string, error) {
|
||||||
instances, err := resolver.Dependencies.Instances.All(ctx)
|
instances, err := resolver.dependencies.Instances.All(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ import (
|
||||||
|
|
||||||
type Resolver struct {
|
type Resolver struct {
|
||||||
component.Base
|
component.Base
|
||||||
Dependencies struct {
|
dependencies struct {
|
||||||
Instances *instances.Instances
|
Instances *instances.Instances
|
||||||
Templating *templating.Templating
|
Templating *templating.Templating
|
||||||
Auth *auth.Auth
|
Auth *auth.Auth
|
||||||
|
|
@ -71,7 +71,7 @@ var (
|
||||||
func (resolver *Resolver) HandleRoute(ctx context.Context, route string) (http.Handler, error) {
|
func (resolver *Resolver) HandleRoute(ctx context.Context, route string) (http.Handler, error) {
|
||||||
// get the resolver template
|
// get the resolver template
|
||||||
tpl := resolverTemplate.Prepare(
|
tpl := resolverTemplate.Prepare(
|
||||||
resolver.Dependencies.Templating,
|
resolver.dependencies.Templating,
|
||||||
templating.Crumbs(
|
templating.Crumbs(
|
||||||
menuResolver,
|
menuResolver,
|
||||||
),
|
),
|
||||||
|
|
@ -103,7 +103,7 @@ func (resolver *Resolver) HandleRoute(ctx context.Context, route string) (http.H
|
||||||
IndexContext: context,
|
IndexContext: context,
|
||||||
}
|
}
|
||||||
|
|
||||||
if resolver.Dependencies.Auth.CheckScope("", scopes.ScopeUserValid, r) != nil {
|
if resolver.dependencies.Auth.CheckScope("", scopes.ScopeUserValid, r) != nil {
|
||||||
ctx.IndexContext.Prefixes = nil
|
ctx.IndexContext.Prefixes = nil
|
||||||
}
|
}
|
||||||
httpx.WriteHTML(tpl.Context(r, ctx), nil, t, "", w, r)
|
httpx.WriteHTML(tpl.Context(r, ctx), nil, t, "", w, r)
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,6 @@ import (
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/templating"
|
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/templating"
|
||||||
"github.com/julienschmidt/httprouter"
|
"github.com/julienschmidt/httprouter"
|
||||||
"github.com/rs/zerolog"
|
"github.com/rs/zerolog"
|
||||||
"github.com/tkw1536/pkglib/lifetime"
|
|
||||||
|
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/instances"
|
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/instances"
|
||||||
"github.com/tkw1536/pkglib/httpx"
|
"github.com/tkw1536/pkglib/httpx"
|
||||||
|
|
@ -20,7 +19,7 @@ import (
|
||||||
|
|
||||||
type Admin struct {
|
type Admin struct {
|
||||||
component.Base
|
component.Base
|
||||||
Dependencies struct {
|
dependencies struct {
|
||||||
Fetchers []component.DistilleryFetcher
|
Fetchers []component.DistilleryFetcher
|
||||||
|
|
||||||
Instances *instances.Instances
|
Instances *instances.Instances
|
||||||
|
|
@ -33,8 +32,6 @@ type Admin struct {
|
||||||
|
|
||||||
Sockets *socket.Sockets
|
Sockets *socket.Sockets
|
||||||
}
|
}
|
||||||
|
|
||||||
Analytics *lifetime.Analytics
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
@ -47,12 +44,12 @@ func (admin *Admin) Routes() component.Routes {
|
||||||
return component.Routes{
|
return component.Routes{
|
||||||
Prefix: "/admin/",
|
Prefix: "/admin/",
|
||||||
CSRF: true,
|
CSRF: true,
|
||||||
Decorator: admin.Dependencies.Auth.Require(false, scopes.ScopeUserAdmin, nil),
|
Decorator: admin.dependencies.Auth.Require(false, scopes.ScopeUserAdmin, nil),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (admin *Admin) Menu(r *http.Request) []component.MenuItem {
|
func (admin *Admin) Menu(r *http.Request) []component.MenuItem {
|
||||||
if admin.Dependencies.Auth.CheckScope("", scopes.ScopeUserAdmin, r) != nil {
|
if admin.dependencies.Auth.CheckScope("", scopes.ScopeUserAdmin, r) != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return []component.MenuItem{
|
return []component.MenuItem{
|
||||||
|
|
@ -65,8 +62,7 @@ func (admin *Admin) Menu(r *http.Request) []component.MenuItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
menuAdmin = component.MenuItem{Title: "Admin", Path: "/admin/"}
|
menuAdmin = component.MenuItem{Title: "Admin", Path: "/admin/"}
|
||||||
menuComponents = component.MenuItem{Title: "Components", Path: "/admin/components/", Priority: component.SmallButton}
|
|
||||||
|
|
||||||
menuUsers = component.MenuItem{Title: "Users", Path: "/admin/users/"}
|
menuUsers = component.MenuItem{Title: "Users", Path: "/admin/users/"}
|
||||||
menuUserCreate = component.MenuItem{Title: "Create User", Path: "/admin/users/create/"}
|
menuUserCreate = component.MenuItem{Title: "Create User", Path: "/admin/users/create/"}
|
||||||
|
|
@ -121,18 +117,6 @@ func (admin *Admin) HandleRoute(ctx context.Context, route string) (handler http
|
||||||
router.Handler(http.MethodPost, route+"users/impersonate", admin.usersImpersonateHandler(ctx))
|
router.Handler(http.MethodPost, route+"users/impersonate", admin.usersImpersonateHandler(ctx))
|
||||||
router.Handler(http.MethodPost, route+"users/unsetpassword", admin.usersUnsetPasswordHandler(ctx))
|
router.Handler(http.MethodPost, route+"users/unsetpassword", admin.usersUnsetPasswordHandler(ctx))
|
||||||
|
|
||||||
// add a handler for the component page
|
|
||||||
{
|
|
||||||
components := admin.components(ctx)
|
|
||||||
router.Handler(http.MethodGet, route+"components", components)
|
|
||||||
}
|
|
||||||
|
|
||||||
// add a handler for the ingredients page
|
|
||||||
{
|
|
||||||
ingredients := admin.ingredients(ctx)
|
|
||||||
router.Handler(http.MethodGet, route+"ingredients/:slug", ingredients)
|
|
||||||
}
|
|
||||||
|
|
||||||
// add a handler for the instance page
|
// add a handler for the instance page
|
||||||
{
|
{
|
||||||
instance := admin.instance(ctx)
|
instance := admin.instance(ctx)
|
||||||
|
|
@ -167,7 +151,7 @@ func (admin *Admin) loginHandler(ctx context.Context) http.Handler {
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the instance
|
// get the instance
|
||||||
instance, err := admin.Dependencies.Instances.WissKI(r.Context(), r.PostFormValue("slug"))
|
instance, err := admin.dependencies.Instances.WissKI(r.Context(), r.PostFormValue("slug"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", 0, httpx.ErrNotFound
|
return "", 0, httpx.ErrNotFound
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,83 +0,0 @@
|
||||||
package admin
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"html/template"
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
|
||||||
"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/templating"
|
|
||||||
"github.com/julienschmidt/httprouter"
|
|
||||||
"github.com/tkw1536/pkglib/httpx"
|
|
||||||
"github.com/tkw1536/pkglib/lifetime"
|
|
||||||
|
|
||||||
_ "embed"
|
|
||||||
)
|
|
||||||
|
|
||||||
//go:embed "html/anal.html"
|
|
||||||
var analHTML []byte
|
|
||||||
var analTemplate = templating.Parse[analContext](
|
|
||||||
"anal.html", analHTML, nil,
|
|
||||||
|
|
||||||
templating.Assets(assets.AssetsAdmin),
|
|
||||||
)
|
|
||||||
|
|
||||||
type analContext struct {
|
|
||||||
templating.RuntimeFlags
|
|
||||||
|
|
||||||
Analytics lifetime.Analytics
|
|
||||||
}
|
|
||||||
|
|
||||||
func (admin *Admin) components(ctx context.Context) http.Handler {
|
|
||||||
tpl := analTemplate.Prepare(
|
|
||||||
admin.Dependencies.Templating,
|
|
||||||
templating.Crumbs(
|
|
||||||
menuAdmin,
|
|
||||||
menuInstances,
|
|
||||||
menuComponents,
|
|
||||||
),
|
|
||||||
templating.Title("Components"),
|
|
||||||
)
|
|
||||||
|
|
||||||
return tpl.HTMLHandler(func(r *http.Request) (ac analContext, err error) {
|
|
||||||
ac.Analytics = *admin.Analytics
|
|
||||||
return
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (admin *Admin) ingredients(ctx context.Context) http.Handler {
|
|
||||||
tpl := analTemplate.Prepare(
|
|
||||||
admin.Dependencies.Templating,
|
|
||||||
templating.Crumbs(
|
|
||||||
menuAdmin,
|
|
||||||
menuInstances,
|
|
||||||
menuInstance,
|
|
||||||
menuIngredients,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
return tpl.HTMLHandlerWithFlags(func(r *http.Request) (ac analContext, funcs []templating.FlagFunc, err error) {
|
|
||||||
slug := httprouter.ParamsFromContext(r.Context()).ByName("slug")
|
|
||||||
|
|
||||||
// find the instance itself!
|
|
||||||
instance, err := admin.Dependencies.Instances.WissKI(r.Context(), slug)
|
|
||||||
if err == instances.ErrWissKINotFound {
|
|
||||||
return ac, nil, httpx.ErrNotFound
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return ac, nil, err
|
|
||||||
}
|
|
||||||
funcs = []templating.FlagFunc{
|
|
||||||
templating.ReplaceCrumb(menuInstance, component.MenuItem{Title: "Instance", Path: template.URL("/admin/instance/" + slug)}),
|
|
||||||
templating.ReplaceCrumb(menuIngredients, component.MenuItem{Title: "Ingredients", Path: template.URL("/admin/instance/" + slug + "/ingredients/")}),
|
|
||||||
templating.Title(instance.Name() + " - Ingredients"),
|
|
||||||
}
|
|
||||||
|
|
||||||
// and get the components
|
|
||||||
ac.Analytics = *instance.Info().Analytics
|
|
||||||
|
|
||||||
return
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
@ -44,7 +44,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(
|
tpl := grantsTemplate.Prepare(
|
||||||
admin.Dependencies.Templating,
|
admin.dependencies.Templating,
|
||||||
templating.Crumbs(
|
templating.Crumbs(
|
||||||
menuAdmin,
|
menuAdmin,
|
||||||
menuInstances,
|
menuInstances,
|
||||||
|
|
@ -100,13 +100,13 @@ func (admin *Admin) postGrants(r *http.Request) (gc grantsContext, funcs []templ
|
||||||
|
|
||||||
if delete {
|
if delete {
|
||||||
// delete the user grant
|
// delete the user grant
|
||||||
err := admin.Dependencies.Policy.Remove(r.Context(), distilleryUser, slug)
|
err := admin.dependencies.Policy.Remove(r.Context(), distilleryUser, slug)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return gc, nil, err
|
return gc, nil, err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// update the grant
|
// update the grant
|
||||||
err := admin.Dependencies.Policy.Set(r.Context(), models.Grant{
|
err := admin.dependencies.Policy.Set(r.Context(), models.Grant{
|
||||||
User: distilleryUser,
|
User: distilleryUser,
|
||||||
Slug: slug,
|
Slug: slug,
|
||||||
|
|
||||||
|
|
@ -127,7 +127,7 @@ func (admin *Admin) postGrants(r *http.Request) (gc grantsContext, funcs []templ
|
||||||
|
|
||||||
func (gc *grantsContext) use(r *http.Request, slug string, admin *Admin) (funcs []templating.FlagFunc, err error) {
|
func (gc *grantsContext) use(r *http.Request, slug string, admin *Admin) (funcs []templating.FlagFunc, err error) {
|
||||||
// find the instance itself
|
// find the instance itself
|
||||||
gc.instance, err = admin.Dependencies.Instances.WissKI(r.Context(), slug)
|
gc.instance, err = admin.dependencies.Instances.WissKI(r.Context(), slug)
|
||||||
if err == instances.ErrWissKINotFound {
|
if err == instances.ErrWissKINotFound {
|
||||||
return nil, httpx.ErrNotFound
|
return nil, httpx.ErrNotFound
|
||||||
}
|
}
|
||||||
|
|
@ -146,12 +146,12 @@ func (gc *grantsContext) use(r *http.Request, slug string, admin *Admin) (funcs
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gc *grantsContext) useGrants(r *http.Request, admin *Admin) (err error) {
|
func (gc *grantsContext) useGrants(r *http.Request, admin *Admin) (err error) {
|
||||||
gc.Grants, err = admin.Dependencies.Policy.Instance(r.Context(), gc.Instance.Slug)
|
gc.Grants, err = admin.dependencies.Policy.Instance(r.Context(), gc.Instance.Slug)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
users, err := admin.Dependencies.Auth.Users(r.Context())
|
users, err := admin.dependencies.Auth.Users(r.Context())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,139 +0,0 @@
|
||||||
<div class="pure-u-1-1">
|
|
||||||
<h2 id="structs">Structs</h2>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{{ range $name, $comp := .Analytics.Components }}
|
|
||||||
<div class="pure-u-1-1" id="{{ $name }}">
|
|
||||||
<div class="padding">
|
|
||||||
<div class="overflow">
|
|
||||||
<table class="pure-table pure-table-bordered">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th colspan="3">
|
|
||||||
{{ $name }}
|
|
||||||
</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{{ range .Groups }}
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
Implements
|
|
||||||
</td>
|
|
||||||
<td colspan="2">
|
|
||||||
<code><a href="#{{.}}">{{ . }}</a></code><br />
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{{ end }}
|
|
||||||
{{ range $name, $comp := .CFields }}
|
|
||||||
<tr>
|
|
||||||
<td>Component Pointer</td>
|
|
||||||
<td>
|
|
||||||
<code>{{ $name }}</code>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<code><a href="#{{ $comp }}">{{ $comp }}</a></code>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{{ end }}
|
|
||||||
{{ range $name, $comp := .DCFields }}
|
|
||||||
<tr>
|
|
||||||
<td>Component Pointer</td>
|
|
||||||
<td>
|
|
||||||
<code>Dependencies/{{ $name }}</code>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<code><a href="#{{ $comp }}">{{ $comp }}</a></code>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{{ end }}
|
|
||||||
{{ range $name, $iface := .IFields }}
|
|
||||||
<tr>
|
|
||||||
<td>Interface Slice</td>
|
|
||||||
<td>
|
|
||||||
<code>{{ $name }}</code>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<code><a href="#{{ $iface }}">[]{{ $iface }}</a></code>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{{ end }}
|
|
||||||
{{ range $name, $iface := .DIFields }}
|
|
||||||
<tr>
|
|
||||||
<td>Interface Slice</td>
|
|
||||||
<td>
|
|
||||||
<code>Dependencies/{{ $name }}</code>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<code><a href="#{{ $iface }}">[]{{ $iface }}</a></code>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{{ end }}
|
|
||||||
{{ range $name, $sig := $comp.Methods }}
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
Method
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<code>{{ $name }}</code>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<code>{{ $sig }}</code>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{{ end }}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
<div class="pure-u-1-1">
|
|
||||||
<h2 id="interfaces">Interfaces</h2>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{{ range $name, $group := .Analytics.Groups }}
|
|
||||||
<div class="pure-u-1-1" id="{{ $name }}">
|
|
||||||
<div class="padding">
|
|
||||||
|
|
||||||
<div class="overflow">
|
|
||||||
<table class="pure-table pure-table-bordered">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th colspan="3">
|
|
||||||
{{ $name }}
|
|
||||||
</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{{ range $name, $sig := $group.Methods }}
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
Method
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<code>{{ $name }}</code>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<code>{{ $sig }}</code>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{{ end }}
|
|
||||||
{{ range $group.Components }}
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
Implemented By
|
|
||||||
</td>
|
|
||||||
<td colspan="2">
|
|
||||||
<code><a href="#{{.}}">{{ . }}</a></code>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{{ end }}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{ end }}
|
|
||||||
|
|
@ -21,7 +21,7 @@ func (admin *Admin) Status(ctx context.Context, QuickInformation bool) (target s
|
||||||
|
|
||||||
group.Go(func() error {
|
group.Go(func() error {
|
||||||
// list all the instances
|
// list all the instances
|
||||||
all, err := admin.Dependencies.Instances.All(ctx)
|
all, err := admin.dependencies.Instances.All(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -47,7 +47,7 @@ func (admin *Admin) Status(ctx context.Context, QuickInformation bool) (target s
|
||||||
flags := component.FetcherFlags{
|
flags := component.FetcherFlags{
|
||||||
Context: ctx,
|
Context: ctx,
|
||||||
}
|
}
|
||||||
for _, o := range admin.Dependencies.Fetchers {
|
for _, o := range admin.dependencies.Fetchers {
|
||||||
o := o
|
o := o
|
||||||
group.Go(func() error {
|
group.Go(func() error {
|
||||||
return o.Fetch(flags, &target)
|
return o.Fetch(flags, &target)
|
||||||
|
|
@ -109,11 +109,10 @@ type indexContext struct {
|
||||||
|
|
||||||
func (admin *Admin) index(ctx context.Context) http.Handler {
|
func (admin *Admin) index(ctx context.Context) http.Handler {
|
||||||
tpl := indexTemplate.Prepare(
|
tpl := indexTemplate.Prepare(
|
||||||
admin.Dependencies.Templating,
|
admin.dependencies.Templating,
|
||||||
templating.Actions(
|
templating.Actions(
|
||||||
menuUsers,
|
menuUsers,
|
||||||
menuInstances,
|
menuInstances,
|
||||||
menuComponents,
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -125,7 +124,7 @@ func (admin *Admin) index(ctx context.Context) http.Handler {
|
||||||
|
|
||||||
func (admin *Admin) instances(ctx context.Context) http.Handler {
|
func (admin *Admin) instances(ctx context.Context) http.Handler {
|
||||||
tpl := instancesTemplate.Prepare(
|
tpl := instancesTemplate.Prepare(
|
||||||
admin.Dependencies.Templating,
|
admin.dependencies.Templating,
|
||||||
templating.Crumbs(
|
templating.Crumbs(
|
||||||
menuAdmin,
|
menuAdmin,
|
||||||
menuInstances,
|
menuInstances,
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ type instanceContext struct {
|
||||||
|
|
||||||
func (admin *Admin) instance(ctx context.Context) http.Handler {
|
func (admin *Admin) instance(ctx context.Context) http.Handler {
|
||||||
tpl := instanceTemplate.Prepare(
|
tpl := instanceTemplate.Prepare(
|
||||||
admin.Dependencies.Templating,
|
admin.dependencies.Templating,
|
||||||
templating.Crumbs(
|
templating.Crumbs(
|
||||||
menuAdmin,
|
menuAdmin,
|
||||||
menuInstances,
|
menuInstances,
|
||||||
|
|
@ -51,7 +51,7 @@ func (admin *Admin) instance(ctx context.Context) http.Handler {
|
||||||
slug := httprouter.ParamsFromContext(r.Context()).ByName("slug")
|
slug := httprouter.ParamsFromContext(r.Context()).ByName("slug")
|
||||||
|
|
||||||
// find the instance itself!
|
// find the instance itself!
|
||||||
instance, err := admin.Dependencies.Instances.WissKI(r.Context(), slug)
|
instance, err := admin.dependencies.Instances.WissKI(r.Context(), slug)
|
||||||
if err == instances.ErrWissKINotFound {
|
if err == instances.ErrWissKINotFound {
|
||||||
return ic, nil, httpx.ErrNotFound
|
return ic, nil, httpx.ErrNotFound
|
||||||
}
|
}
|
||||||
|
|
@ -70,7 +70,6 @@ func (admin *Admin) instance(ctx context.Context) http.Handler {
|
||||||
templating.ReplaceCrumb(menuInstance, component.MenuItem{Title: "Instance", Path: template.URL("/admin/instance/" + slug)}),
|
templating.ReplaceCrumb(menuInstance, component.MenuItem{Title: "Instance", Path: template.URL("/admin/instance/" + slug)}),
|
||||||
templating.ReplaceAction(menuRebuild, component.MenuItem{Title: "Rebuild", Path: template.URL("/admin/rebuild/" + slug)}),
|
templating.ReplaceAction(menuRebuild, component.MenuItem{Title: "Rebuild", Path: template.URL("/admin/rebuild/" + slug)}),
|
||||||
templating.ReplaceAction(menuGrants, component.MenuItem{Title: "Grants", Path: template.URL("/admin/grants/" + slug)}),
|
templating.ReplaceAction(menuGrants, component.MenuItem{Title: "Grants", Path: template.URL("/admin/grants/" + slug)}),
|
||||||
templating.ReplaceAction(menuIngredients, component.MenuItem{Title: "Ingredients", Path: template.URL("/admin/ingredients/" + slug), Priority: component.SmallButton}),
|
|
||||||
|
|
||||||
templating.Title(instance.Slug),
|
templating.Title(instance.Slug),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ import (
|
||||||
|
|
||||||
func (admin *Admin) instanceProvision(ctx context.Context) http.Handler {
|
func (admin *Admin) instanceProvision(ctx context.Context) http.Handler {
|
||||||
tpl := instanceSystemTemplate.Prepare(
|
tpl := instanceSystemTemplate.Prepare(
|
||||||
admin.Dependencies.Templating,
|
admin.dependencies.Templating,
|
||||||
|
|
||||||
templating.Title("Provision New Instance"),
|
templating.Title("Provision New Instance"),
|
||||||
templating.Assets(assets.AssetsAdminProvision),
|
templating.Assets(assets.AssetsAdminProvision),
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ func (isc *instanceSystemContext) prepare(rebuild bool) {
|
||||||
|
|
||||||
func (admin *Admin) instanceRebuild(ctx context.Context) http.Handler {
|
func (admin *Admin) instanceRebuild(ctx context.Context) http.Handler {
|
||||||
tpl := instanceSystemTemplate.Prepare(
|
tpl := instanceSystemTemplate.Prepare(
|
||||||
admin.Dependencies.Templating,
|
admin.dependencies.Templating,
|
||||||
|
|
||||||
templating.Title("Rebuild Instance"),
|
templating.Title("Rebuild Instance"),
|
||||||
templating.Assets(assets.AssetsAdminRebuild),
|
templating.Assets(assets.AssetsAdminRebuild),
|
||||||
|
|
@ -65,7 +65,7 @@ func (admin *Admin) instanceRebuild(ctx context.Context) http.Handler {
|
||||||
slug := httprouter.ParamsFromContext(r.Context()).ByName("slug")
|
slug := httprouter.ParamsFromContext(r.Context()).ByName("slug")
|
||||||
|
|
||||||
var instance *wisski.WissKI
|
var instance *wisski.WissKI
|
||||||
instance, err = admin.Dependencies.Instances.WissKI(r.Context(), slug)
|
instance, err = admin.dependencies.Instances.WissKI(r.Context(), slug)
|
||||||
if err == instances.ErrWissKINotFound {
|
if err == instances.ErrWissKINotFound {
|
||||||
return isc, nil, httpx.ErrNotFound
|
return isc, nil, httpx.ErrNotFound
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ func (sockets *Sockets) Actions() ActionMap {
|
||||||
return map[string]Action{
|
return map[string]Action{
|
||||||
// generic actions
|
// generic actions
|
||||||
"backup": sockets.Generic(scopes.ScopeUserAdmin, "", 0, func(ctx context.Context, sockets *Sockets, in io.Reader, out io.Writer, params ...string) error {
|
"backup": sockets.Generic(scopes.ScopeUserAdmin, "", 0, func(ctx context.Context, sockets *Sockets, in io.Reader, out io.Writer, params ...string) error {
|
||||||
return sockets.Dependencies.Exporter.MakeExport(
|
return sockets.dependencies.Exporter.MakeExport(
|
||||||
ctx,
|
ctx,
|
||||||
out,
|
out,
|
||||||
exporter.ExportTask{
|
exporter.ExportTask{
|
||||||
|
|
@ -35,7 +35,7 @@ func (sockets *Sockets) Actions() ActionMap {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
instance, err := sockets.Dependencies.Provision.Provision(
|
instance, err := sockets.dependencies.Provision.Provision(
|
||||||
out,
|
out,
|
||||||
ctx,
|
ctx,
|
||||||
flags,
|
flags,
|
||||||
|
|
@ -54,7 +54,7 @@ func (sockets *Sockets) Actions() ActionMap {
|
||||||
// instance-specific actions!
|
// instance-specific actions!
|
||||||
|
|
||||||
"snapshot": sockets.Instance(scopes.ScopeUserAdmin, "", 0, func(ctx context.Context, socket *Sockets, instance *wisski.WissKI, in io.Reader, out io.Writer, params ...string) error {
|
"snapshot": sockets.Instance(scopes.ScopeUserAdmin, "", 0, func(ctx context.Context, socket *Sockets, instance *wisski.WissKI, in io.Reader, out io.Writer, params ...string) error {
|
||||||
return socket.Dependencies.Exporter.MakeExport(
|
return socket.dependencies.Exporter.MakeExport(
|
||||||
ctx,
|
ctx,
|
||||||
out,
|
out,
|
||||||
exporter.ExportTask{
|
exporter.ExportTask{
|
||||||
|
|
@ -86,7 +86,7 @@ func (sockets *Sockets) Actions() ActionMap {
|
||||||
return instance.Barrel().Stack().Down(ctx, out)
|
return instance.Barrel().Stack().Down(ctx, out)
|
||||||
}),
|
}),
|
||||||
"purge": sockets.Instance(scopes.ScopeUserAdmin, "", 0, func(ctx context.Context, sockets *Sockets, instance *wisski.WissKI, in io.Reader, out io.Writer, params ...string) error {
|
"purge": sockets.Instance(scopes.ScopeUserAdmin, "", 0, func(ctx context.Context, sockets *Sockets, instance *wisski.WissKI, in io.Reader, out io.Writer, params ...string) error {
|
||||||
return sockets.Dependencies.Purger.Purge(ctx, out, instance.Slug)
|
return sockets.dependencies.Purger.Purge(ctx, out, instance.Slug)
|
||||||
}),
|
}),
|
||||||
"never": sockets.Generic(scopes.ScopeNever, "", 0, func(ctx context.Context, sockets *Sockets, in io.Reader, out io.Writer, params ...string) error {
|
"never": sockets.Generic(scopes.ScopeNever, "", 0, func(ctx context.Context, sockets *Sockets, in io.Reader, out io.Writer, params ...string) error {
|
||||||
panic("never called")
|
panic("never called")
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ type Sockets struct {
|
||||||
|
|
||||||
actions lazy.Lazy[ActionMap]
|
actions lazy.Lazy[ActionMap]
|
||||||
|
|
||||||
Dependencies struct {
|
dependencies struct {
|
||||||
Provision *provision.Provision
|
Provision *provision.Provision
|
||||||
Instances *instances.Instances
|
Instances *instances.Instances
|
||||||
Exporter *exporter.Exporter
|
Exporter *exporter.Exporter
|
||||||
|
|
@ -40,7 +40,7 @@ func (socket *Sockets) Routes() component.Routes {
|
||||||
return component.Routes{
|
return component.Routes{
|
||||||
Prefix: "/api/v1/ws",
|
Prefix: "/api/v1/ws",
|
||||||
Exact: true,
|
Exact: true,
|
||||||
Decorator: socket.Dependencies.Auth.Require(true, scopes.ScopeUserValid, nil),
|
Decorator: socket.dependencies.Auth.Require(true, scopes.ScopeUserValid, nil),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -54,7 +54,7 @@ func (sockets *Sockets) HandleRoute(ctx context.Context, path string) (http.Hand
|
||||||
// Serve handles a connection to the websocket api
|
// Serve handles a connection to the websocket api
|
||||||
func (socket *Sockets) Serve(conn httpx.WebSocketConnection) {
|
func (socket *Sockets) Serve(conn httpx.WebSocketConnection) {
|
||||||
// handle the websocket connection!
|
// handle the websocket connection!
|
||||||
name, err := socket.actions.Get(socket.Actions).Handle(socket.Dependencies.Auth, conn)
|
name, err := socket.actions.Get(socket.Actions).Handle(socket.dependencies.Auth, conn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
zerolog.Ctx(conn.Context()).Err(err).Str("name", name).Msg("Error handling websocket")
|
zerolog.Ctx(conn.Context()).Err(err).Str("name", name).Msg("Error handling websocket")
|
||||||
}
|
}
|
||||||
|
|
@ -80,7 +80,7 @@ func (sockets *Sockets) Instance(scope component.Scope, scopeParam string, numPa
|
||||||
|
|
||||||
NumParams: numParams + 1,
|
NumParams: numParams + 1,
|
||||||
Handle: func(ctx context.Context, in io.Reader, out io.Writer, params ...string) error {
|
Handle: func(ctx context.Context, in io.Reader, out io.Writer, params ...string) error {
|
||||||
instance, err := sockets.Dependencies.Instances.WissKI(ctx, params[0])
|
instance, err := sockets.dependencies.Instances.WissKI(ctx, params[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ type usersContext struct {
|
||||||
|
|
||||||
func (admin *Admin) users(ctx context.Context) http.Handler {
|
func (admin *Admin) users(ctx context.Context) http.Handler {
|
||||||
tpl := usersTemplate.Prepare(
|
tpl := usersTemplate.Prepare(
|
||||||
admin.Dependencies.Templating,
|
admin.dependencies.Templating,
|
||||||
templating.Crumbs(
|
templating.Crumbs(
|
||||||
menuAdmin,
|
menuAdmin,
|
||||||
menuUsers,
|
menuUsers,
|
||||||
|
|
@ -45,7 +45,7 @@ func (admin *Admin) users(ctx context.Context) http.Handler {
|
||||||
|
|
||||||
return tpl.HTMLHandler(func(r *http.Request) (uc usersContext, err error) {
|
return tpl.HTMLHandler(func(r *http.Request) (uc usersContext, err error) {
|
||||||
uc.Error = r.URL.Query().Get("error")
|
uc.Error = r.URL.Query().Get("error")
|
||||||
uc.Users, err = admin.Dependencies.Auth.Users(r.Context())
|
uc.Users, err = admin.dependencies.Auth.Users(r.Context())
|
||||||
return
|
return
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -72,7 +72,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(
|
tpl := userCreateTemplate.Prepare(
|
||||||
admin.Dependencies.Templating,
|
admin.dependencies.Templating,
|
||||||
templating.Crumbs(
|
templating.Crumbs(
|
||||||
menuAdmin,
|
menuAdmin,
|
||||||
menuUsers,
|
menuUsers,
|
||||||
|
|
@ -102,7 +102,7 @@ func (admin *Admin) createUser(ctx context.Context) http.Handler {
|
||||||
}
|
}
|
||||||
|
|
||||||
// check the password policy
|
// check the password policy
|
||||||
err = admin.Dependencies.Auth.CheckPasswordPolicy(cu.Passsword, cu.User)
|
err = admin.dependencies.Auth.CheckPasswordPolicy(cu.Passsword, cu.User)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cu, err
|
return cu, err
|
||||||
}
|
}
|
||||||
|
|
@ -112,7 +112,7 @@ func (admin *Admin) createUser(ctx context.Context) http.Handler {
|
||||||
|
|
||||||
RenderSuccess: func(cu createUserResult, values map[string]string, w http.ResponseWriter, r *http.Request) error {
|
RenderSuccess: func(cu createUserResult, values map[string]string, w http.ResponseWriter, r *http.Request) error {
|
||||||
// create the user
|
// create the user
|
||||||
user, err := admin.Dependencies.Auth.CreateUser(r.Context(), cu.User)
|
user, err := admin.dependencies.Auth.CreateUser(r.Context(), cu.User)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -151,14 +151,14 @@ func (admin *Admin) useraction(ctx context.Context, name string, action func(r *
|
||||||
}
|
}
|
||||||
|
|
||||||
username := r.PostFormValue("user")
|
username := r.PostFormValue("user")
|
||||||
user, err := admin.Dependencies.Auth.User(r.Context(), username)
|
user, err := admin.dependencies.Auth.User(r.Context(), username)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Err(err).Str("action", name).Msg("failed to get user")
|
logger.Err(err).Str("action", name).Msg("failed to get user")
|
||||||
httpx.HTMLInterceptor.Fallback.ServeHTTP(w, r)
|
httpx.HTMLInterceptor.Fallback.ServeHTTP(w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
me, err := admin.Dependencies.Auth.UserOfSession(r)
|
me, err := admin.dependencies.Auth.UserOfSession(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Err(err).Str("action", name).Msg("failed to get current user")
|
logger.Err(err).Str("action", name).Msg("failed to get current user")
|
||||||
httpx.HTMLInterceptor.Fallback.ServeHTTP(w, r)
|
httpx.HTMLInterceptor.Fallback.ServeHTTP(w, r)
|
||||||
|
|
@ -241,7 +241,7 @@ func (admin *Admin) usersImpersonateHandler(ctx context.Context) http.Handler {
|
||||||
}
|
}
|
||||||
|
|
||||||
username := r.PostFormValue("user")
|
username := r.PostFormValue("user")
|
||||||
user, err := admin.Dependencies.Auth.User(r.Context(), username)
|
user, err := admin.dependencies.Auth.User(r.Context(), username)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Err(err).Str("action", "impersonate").Msg("failed to get user")
|
logger.Err(err).Str("action", "impersonate").Msg("failed to get user")
|
||||||
httpx.HTMLInterceptor.Fallback.ServeHTTP(w, r)
|
httpx.HTMLInterceptor.Fallback.ServeHTTP(w, r)
|
||||||
|
|
@ -249,7 +249,7 @@ func (admin *Admin) usersImpersonateHandler(ctx context.Context) http.Handler {
|
||||||
}
|
}
|
||||||
|
|
||||||
// login the user into the session of the provided user
|
// login the user into the session of the provided user
|
||||||
if err := admin.Dependencies.Auth.Login(w, r, user); err != nil {
|
if err := admin.dependencies.Auth.Login(w, r, user); err != nil {
|
||||||
logger.Err(err).Str("action", "impersonate").Msg("failed to login user")
|
logger.Err(err).Str("action", "impersonate").Msg("failed to login user")
|
||||||
httpx.HTMLInterceptor.Fallback.ServeHTTP(w, r)
|
httpx.HTMLInterceptor.Fallback.ServeHTTP(w, r)
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ import (
|
||||||
|
|
||||||
type Cron struct {
|
type Cron struct {
|
||||||
component.Base
|
component.Base
|
||||||
Dependencies struct {
|
dependencies struct {
|
||||||
Tasks []component.Cronable
|
Tasks []component.Cronable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -52,11 +52,11 @@ func (control *Cron) Listen(ctx context.Context) (<-chan struct{}, func()) {
|
||||||
// Once should not be called concurrently with Cron.
|
// Once should not be called concurrently with Cron.
|
||||||
func (control *Cron) Once(ctx context.Context) {
|
func (control *Cron) Once(ctx context.Context) {
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
wg.Add(len(control.Dependencies.Tasks))
|
wg.Add(len(control.dependencies.Tasks))
|
||||||
|
|
||||||
zerolog.Ctx(ctx).Info().Time("time", time.Now()).Msg("Starting Cron")
|
zerolog.Ctx(ctx).Info().Time("time", time.Now()).Msg("Starting Cron")
|
||||||
|
|
||||||
for _, task := range control.Dependencies.Tasks {
|
for _, task := range control.dependencies.Tasks {
|
||||||
go func(task component.Cronable) {
|
go func(task component.Cronable) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ import (
|
||||||
|
|
||||||
type Home struct {
|
type Home struct {
|
||||||
component.Base
|
component.Base
|
||||||
Dependencies struct {
|
dependencies struct {
|
||||||
ListInstances *list.ListInstances
|
ListInstances *list.ListInstances
|
||||||
Templating *templating.Templating
|
Templating *templating.Templating
|
||||||
}
|
}
|
||||||
|
|
@ -55,7 +55,7 @@ func (home *Home) HandleRoute(ctx context.Context, route string) (http.Handler,
|
||||||
}
|
}
|
||||||
|
|
||||||
func (home *Home) serveWissKI(w http.ResponseWriter, slug string, r *http.Request) {
|
func (home *Home) serveWissKI(w http.ResponseWriter, slug string, r *http.Request) {
|
||||||
if _, ok := home.Dependencies.ListInstances.Names()[slug]; !ok {
|
if _, ok := home.dependencies.ListInstances.Names()[slug]; !ok {
|
||||||
// Get(nil) guaranteed to work by precondition
|
// Get(nil) guaranteed to work by precondition
|
||||||
w.WriteHeader(http.StatusNotFound)
|
w.WriteHeader(http.StatusNotFound)
|
||||||
fmt.Fprintf(w, "WissKI %q not found\n", slug)
|
fmt.Fprintf(w, "WissKI %q not found\n", slug)
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ func (home *Home) publicHandler(ctx context.Context) http.Handler {
|
||||||
title := home.Config.Home.Title
|
title := home.Config.Home.Title
|
||||||
|
|
||||||
tpl := publicTemplate.Prepare(
|
tpl := publicTemplate.Prepare(
|
||||||
home.Dependencies.Templating,
|
home.dependencies.Templating,
|
||||||
// set title and menu item
|
// set title and menu item
|
||||||
templating.Title(title),
|
templating.Title(title),
|
||||||
templating.Crumbs(
|
templating.Crumbs(
|
||||||
|
|
@ -59,7 +59,7 @@ func (home *Home) publicHandler(ctx context.Context) http.Handler {
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
about := home.Dependencies.Templating.GetCustomizable(aboutTemplate)
|
about := home.dependencies.Templating.GetCustomizable(aboutTemplate)
|
||||||
|
|
||||||
return tpl.HTMLHandler(func(r *http.Request) (pc publicContext, err error) {
|
return tpl.HTMLHandler(func(r *http.Request) (pc publicContext, err error) {
|
||||||
// only act on the root path!
|
// only act on the root path!
|
||||||
|
|
@ -72,7 +72,7 @@ func (home *Home) publicHandler(ctx context.Context) http.Handler {
|
||||||
|
|
||||||
// prepare about
|
// prepare about
|
||||||
pc.aboutContext.Logo = logoHTML
|
pc.aboutContext.Logo = logoHTML
|
||||||
pc.aboutContext.Instances = home.Dependencies.ListInstances.Infos()
|
pc.aboutContext.Instances = home.dependencies.ListInstances.Infos()
|
||||||
pc.aboutContext.SelfRedirect = home.Config.Home.SelfRedirect.String()
|
pc.aboutContext.SelfRedirect = home.Config.Home.SelfRedirect.String()
|
||||||
|
|
||||||
// render the about template
|
// render the about template
|
||||||
|
|
@ -85,7 +85,7 @@ func (home *Home) publicHandler(ctx context.Context) http.Handler {
|
||||||
pc.About = template.HTML(builder.String())
|
pc.About = template.HTML(builder.String())
|
||||||
|
|
||||||
// check if we should show the list of WissKIs
|
// check if we should show the list of WissKIs
|
||||||
pc.ListEnabled = home.Dependencies.ListInstances.ShouldShowList(r)
|
pc.ListEnabled = home.dependencies.ListInstances.ShouldShowList(r)
|
||||||
|
|
||||||
// title of the list
|
// title of the list
|
||||||
pc.ListTitle = home.Config.Home.List.Title
|
pc.ListTitle = home.Config.Home.List.Title
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ import (
|
||||||
|
|
||||||
type Legal struct {
|
type Legal struct {
|
||||||
component.Base
|
component.Base
|
||||||
Dependencies struct {
|
dependencies struct {
|
||||||
Static *assets.Static
|
Static *assets.Static
|
||||||
Templating *templating.Templating
|
Templating *templating.Templating
|
||||||
}
|
}
|
||||||
|
|
@ -59,7 +59,7 @@ var (
|
||||||
|
|
||||||
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(
|
tpl := legalTemplate.Prepare(
|
||||||
legal.Dependencies.Templating,
|
legal.dependencies.Templating,
|
||||||
templating.Crumbs(
|
templating.Crumbs(
|
||||||
menuLegal,
|
menuLegal,
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ import (
|
||||||
// API implements an API to list all instances
|
// API implements an API to list all instances
|
||||||
type API struct {
|
type API struct {
|
||||||
component.Base
|
component.Base
|
||||||
Dependencies struct {
|
dependencies struct {
|
||||||
ListInstances *ListInstances
|
ListInstances *ListInstances
|
||||||
Auth *auth.Auth
|
Auth *auth.Auth
|
||||||
}
|
}
|
||||||
|
|
@ -42,15 +42,15 @@ type APISystem struct {
|
||||||
func (a *API) HandleRoute(ctx context.Context, path string) (http.Handler, error) {
|
func (a *API) HandleRoute(ctx context.Context, path string) (http.Handler, error) {
|
||||||
return &api.Handler[[]APISystem]{
|
return &api.Handler[[]APISystem]{
|
||||||
Config: a.Config,
|
Config: a.Config,
|
||||||
Auth: a.Dependencies.Auth,
|
Auth: a.dependencies.Auth,
|
||||||
|
|
||||||
Methods: []string{"GET"},
|
Methods: []string{"GET"},
|
||||||
Scope: scopes.ScopeInstanceDirectory,
|
Scope: scopes.ScopeInstanceDirectory,
|
||||||
|
|
||||||
Handler: func(s string, r *http.Request) ([]APISystem, error) {
|
Handler: func(s string, r *http.Request) ([]APISystem, error) {
|
||||||
var statuses []status.WissKI
|
var statuses []status.WissKI
|
||||||
if a.Dependencies.ListInstances.ShouldShowList(r) {
|
if a.dependencies.ListInstances.ShouldShowList(r) {
|
||||||
statuses = a.Dependencies.ListInstances.infos.Get(nil)
|
statuses = a.dependencies.ListInstances.infos.Get(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(statuses) == 0 {
|
if len(statuses) == 0 {
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ type ListInstances struct {
|
||||||
names lazy.Lazy[map[string]struct{}] // instance names
|
names lazy.Lazy[map[string]struct{}] // instance names
|
||||||
infos lazy.Lazy[[]status.WissKI] // list of home instances (updated via cron)
|
infos lazy.Lazy[[]status.WissKI] // list of home instances (updated via cron)
|
||||||
|
|
||||||
Dependencies struct {
|
dependencies struct {
|
||||||
Auth *auth.Auth
|
Auth *auth.Auth
|
||||||
Instances *instances.Instances
|
Instances *instances.Instances
|
||||||
}
|
}
|
||||||
|
|
@ -42,7 +42,7 @@ func (li *ListInstances) ShouldShowList(r *http.Request) bool {
|
||||||
return allowPrivate
|
return allowPrivate
|
||||||
}
|
}
|
||||||
|
|
||||||
_, user, _ := li.Dependencies.Auth.SessionOf(r)
|
_, user, _ := li.dependencies.Auth.SessionOf(r)
|
||||||
if user == nil {
|
if user == nil {
|
||||||
return allowPublic
|
return allowPublic
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -82,7 +82,7 @@ func (li *ListInstances) Cron(ctx context.Context) (err error) {
|
||||||
|
|
||||||
// getNames returns the names of the given instances
|
// getNames returns the names of the given instances
|
||||||
func (li *ListInstances) getNames(ctx context.Context) (map[string]struct{}, error) {
|
func (li *ListInstances) getNames(ctx context.Context) (map[string]struct{}, error) {
|
||||||
wissKIs, err := li.Dependencies.Instances.All(ctx)
|
wissKIs, err := li.dependencies.Instances.All(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -97,7 +97,7 @@ func (li *ListInstances) getNames(ctx context.Context) (map[string]struct{}, err
|
||||||
// getInfos returns the names of the given instances
|
// getInfos returns the names of the given instances
|
||||||
func (li *ListInstances) getInfos(ctx context.Context) ([]status.WissKI, error) {
|
func (li *ListInstances) getInfos(ctx context.Context) ([]status.WissKI, error) {
|
||||||
// find all the WissKIs
|
// find all the WissKIs
|
||||||
wissKIs, err := li.Dependencies.Instances.All(ctx)
|
wissKIs, err := li.dependencies.Instances.All(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ import (
|
||||||
|
|
||||||
type API struct {
|
type API struct {
|
||||||
component.Base
|
component.Base
|
||||||
Dependencies struct {
|
dependencies struct {
|
||||||
Auth *auth.Auth
|
Auth *auth.Auth
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -31,7 +31,7 @@ func (api *API) Routes() component.Routes {
|
||||||
func (a *API) HandleRoute(ctx context.Context, path string) (http.Handler, error) {
|
func (a *API) HandleRoute(ctx context.Context, path string) (http.Handler, error) {
|
||||||
return &api.Handler[[]Item]{
|
return &api.Handler[[]Item]{
|
||||||
Config: a.Config,
|
Config: a.Config,
|
||||||
Auth: a.Dependencies.Auth,
|
Auth: a.dependencies.Auth,
|
||||||
|
|
||||||
Methods: []string{"GET"},
|
Methods: []string{"GET"},
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ import (
|
||||||
|
|
||||||
type News struct {
|
type News struct {
|
||||||
component.Base
|
component.Base
|
||||||
Dependencies struct {
|
dependencies struct {
|
||||||
Templating *templating.Templating
|
Templating *templating.Templating
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -104,8 +104,8 @@ func Items() ([]Item, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
slices.SortFunc(items, func(a, b Item) bool {
|
slices.SortFunc(items, func(a, b Item) int {
|
||||||
return !a.Date.Before(b.Date)
|
return a.Date.Compare(b.Date)
|
||||||
})
|
})
|
||||||
|
|
||||||
return items, nil
|
return items, nil
|
||||||
|
|
@ -132,7 +132,7 @@ var (
|
||||||
// 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(
|
tpl := newsTemplate.Prepare(
|
||||||
news.Dependencies.Templating,
|
news.dependencies.Templating,
|
||||||
templating.Crumbs(
|
templating.Crumbs(
|
||||||
menuNews,
|
menuNews,
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ import (
|
||||||
// Server represents the running control server.
|
// Server represents the running control server.
|
||||||
type Server struct {
|
type Server struct {
|
||||||
component.Base
|
component.Base
|
||||||
Dependencies struct {
|
dependencies struct {
|
||||||
Routeables []component.Routeable
|
Routeables []component.Routeable
|
||||||
Cronables []component.Cronable
|
Cronables []component.Cronable
|
||||||
|
|
||||||
|
|
@ -66,7 +66,7 @@ func (server *Server) Server(ctx context.Context, progress io.Writer) (public ht
|
||||||
csrfProtector := server.csrf()
|
csrfProtector := server.csrf()
|
||||||
|
|
||||||
// iterate over all the handler
|
// iterate over all the handler
|
||||||
for _, s := range server.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()).
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ func (server *Server) Stack() component.StackWithResources {
|
||||||
"SELF_OVERRIDES_FILE": server.Config.Paths.OverridesJSON,
|
"SELF_OVERRIDES_FILE": server.Config.Paths.OverridesJSON,
|
||||||
"SELF_RESOLVER_BLOCK_FILE": server.Config.Paths.ResolverBlocks,
|
"SELF_RESOLVER_BLOCK_FILE": server.Config.Paths.ResolverBlocks,
|
||||||
|
|
||||||
"CUSTOM_ASSETS_PATH": server.Dependencies.Templating.CustomAssetsPath(),
|
"CUSTOM_ASSETS_PATH": server.dependencies.Templating.CustomAssetsPath(),
|
||||||
},
|
},
|
||||||
|
|
||||||
CopyContextFiles: []string{bootstrap.Executable},
|
CopyContextFiles: []string{bootstrap.Executable},
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ type RuntimeFlags struct {
|
||||||
CSRF template.HTML // csrf data (if any)
|
CSRF template.HTML // csrf data (if any)
|
||||||
}
|
}
|
||||||
|
|
||||||
var runtimeFlagsName = reflectx.MakeType[RuntimeFlags]().Name()
|
var runtimeFlagsName = reflectx.TypeFor[RuntimeFlags]().Name()
|
||||||
|
|
||||||
// Clone clones this flags
|
// Clone clones this flags
|
||||||
func (flags Flags) Clone() Flags {
|
func (flags Flags) Clone() Flags {
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ func (tpl *Templating) buildMenu(r *http.Request) []component.MenuItem {
|
||||||
|
|
||||||
// get the static menu items, and then return all the regular ones
|
// get the static menu items, and then return all the regular ones
|
||||||
var items []component.MenuItem
|
var items []component.MenuItem
|
||||||
for _, m := range tpl.Dependencies.Menuable {
|
for _, m := range tpl.dependencies.Menuable {
|
||||||
items = append(items, m.Menu(r)...)
|
items = append(items, m.Menu(r)...)
|
||||||
}
|
}
|
||||||
for i, item := range items {
|
for i, item := range items {
|
||||||
|
|
@ -31,8 +31,8 @@ func (tpl *Templating) buildMenu(r *http.Request) []component.MenuItem {
|
||||||
// Menu returns a list of menu items provided by routeables
|
// Menu returns a list of menu items provided by routeables
|
||||||
func (tpl *Templating) Menu(r *http.Request) []component.MenuItem {
|
func (tpl *Templating) Menu(r *http.Request) []component.MenuItem {
|
||||||
return tpl.menu.Get(func() []component.MenuItem {
|
return tpl.menu.Get(func() []component.MenuItem {
|
||||||
items := make([]component.MenuItem, 0, len(tpl.Dependencies.Routeables))
|
items := make([]component.MenuItem, 0, len(tpl.dependencies.Routeables))
|
||||||
for _, route := range tpl.Dependencies.Routeables {
|
for _, route := range tpl.dependencies.Routeables {
|
||||||
routes := route.Routes()
|
routes := route.Routes()
|
||||||
if routes.MenuTitle == "" {
|
if routes.MenuTitle == "" {
|
||||||
continue
|
continue
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ type Parsed[C any] struct {
|
||||||
// If base is not nil, every template associated with the base template is copied into the given template.
|
// If base is not nil, every template associated with the base template is copied into the given template.
|
||||||
// Functions will be applied on creation time to represent the context for the given template.
|
// Functions will be applied on creation time to represent the context for the given template.
|
||||||
func Parse[C any](name string, source []byte, base *template.Template, funcs ...FlagFunc) Parsed[C] {
|
func Parse[C any](name string, source []byte, base *template.Template, funcs ...FlagFunc) Parsed[C] {
|
||||||
tp := reflectx.MakeType[C]()
|
tp := reflectx.TypeFor[C]()
|
||||||
|
|
||||||
// determine if we have an embedded field in the struct
|
// determine if we have an embedded field in the struct
|
||||||
var hasEmbed bool
|
var hasEmbed bool
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import (
|
||||||
// Templating implements templating customization
|
// Templating implements templating customization
|
||||||
type Templating struct {
|
type Templating struct {
|
||||||
component.Base
|
component.Base
|
||||||
Dependencies struct {
|
dependencies struct {
|
||||||
Routeables []component.Routeable
|
Routeables []component.Routeable
|
||||||
Menuable []component.Menuable
|
Menuable []component.Menuable
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ func (*SQL) BackupName() string {
|
||||||
// Backup makes a backup of all SQL databases into the path dest.
|
// Backup makes a backup of all SQL databases into the path dest.
|
||||||
func (sql *SQL) Backup(scontext *component.StagingContext) error {
|
func (sql *SQL) Backup(scontext *component.StagingContext) error {
|
||||||
return scontext.AddFile("", func(ctx context.Context, file io.Writer) error {
|
return scontext.AddFile("", func(ctx context.Context, file io.Writer) error {
|
||||||
code := sql.Stack().Exec(ctx, stream.NewIOStream(file, scontext.Progress(), nil, 0), "sql", SQlDumpExecutable, "--all-databases")()
|
code := sql.Stack().Exec(ctx, stream.NewIOStream(file, scontext.Progress(), nil), "sql", SQlDumpExecutable, "--all-databases")()
|
||||||
if code != 0 {
|
if code != 0 {
|
||||||
return errSQLBackup
|
return errSQLBackup
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ func (sql *SQL) Snapshot(wisski models.Instance, scontext *component.StagingCont
|
||||||
|
|
||||||
// SnapshotDB makes a backup of the sql database into dest.
|
// SnapshotDB makes a backup of the sql database into dest.
|
||||||
func (sql *SQL) SnapshotDB(ctx context.Context, progress io.Writer, dest io.Writer, database string) error {
|
func (sql *SQL) SnapshotDB(ctx context.Context, progress io.Writer, dest io.Writer, database string) error {
|
||||||
code := sql.Stack().Exec(ctx, stream.NewIOStream(dest, progress, nil, 0), "sql", SQlDumpExecutable, "--databases", database)()
|
code := sql.Stack().Exec(ctx, stream.NewIOStream(dest, progress, nil), "sql", SQlDumpExecutable, "--databases", database)()
|
||||||
if code != 0 {
|
if code != 0 {
|
||||||
return errSQLBackup
|
return errSQLBackup
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import (
|
||||||
|
|
||||||
type SQL struct {
|
type SQL struct {
|
||||||
component.Base
|
component.Base
|
||||||
Dependencies struct {
|
dependencies struct {
|
||||||
Tables []component.Table
|
Tables []component.Table
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ var (
|
||||||
|
|
||||||
func (*InstanceTable) TableInfo() component.TableInfo {
|
func (*InstanceTable) TableInfo() component.TableInfo {
|
||||||
return component.TableInfo{
|
return component.TableInfo{
|
||||||
Model: reflectx.MakeType[models.Instance](),
|
Model: reflectx.TypeFor[models.Instance](),
|
||||||
Name: models.InstanceTable,
|
Name: models.InstanceTable,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -33,7 +33,7 @@ var (
|
||||||
|
|
||||||
func (*LockTable) TableInfo() component.TableInfo {
|
func (*LockTable) TableInfo() component.TableInfo {
|
||||||
return component.TableInfo{
|
return component.TableInfo{
|
||||||
Model: reflectx.MakeType[models.Lock](),
|
Model: reflectx.TypeFor[models.Lock](),
|
||||||
Name: models.LockTable,
|
Name: models.LockTable,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -104,7 +104,7 @@ func (sql *SQL) Update(ctx context.Context, progress io.Writer) error {
|
||||||
|
|
||||||
// migrate all of the tables!
|
// migrate all of the tables!
|
||||||
return logging.LogOperation(func() error {
|
return logging.LogOperation(func() error {
|
||||||
for _, table := range sql.Dependencies.Tables {
|
for _, table := range sql.dependencies.Tables {
|
||||||
info := table.TableInfo()
|
info := table.TableInfo()
|
||||||
logging.LogMessage(progress, "migrating %q table", table.Name())
|
logging.LogMessage(progress, "migrating %q table", table.Name())
|
||||||
db, err := sql.queryTable(ctx, false, info.Name)
|
db, err := sql.queryTable(ctx, false, info.Name)
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ func (ssh2 *SSH2) Routes() component.Routes {
|
||||||
func (ssh2 *SSH2) HandleRoute(ctx context.Context, path string) (http.Handler, error) {
|
func (ssh2 *SSH2) HandleRoute(ctx context.Context, path string) (http.Handler, error) {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
// fetch the global keys
|
// fetch the global keys
|
||||||
gkeys, err := ssh2.Dependencies.Keys.Admin(r.Context())
|
gkeys, err := ssh2.dependencies.Keys.Admin(r.Context())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
httpx.TextInterceptor.Intercept(w, r, err)
|
httpx.TextInterceptor.Intercept(w, r, err)
|
||||||
return
|
return
|
||||||
|
|
@ -33,7 +33,7 @@ func (ssh2 *SSH2) HandleRoute(ctx context.Context, path string) (http.Handler, e
|
||||||
}
|
}
|
||||||
|
|
||||||
// fetch the instance
|
// fetch the instance
|
||||||
instance, err := ssh2.Dependencies.Instances.WissKI(r.Context(), slug)
|
instance, err := ssh2.dependencies.Instances.WissKI(r.Context(), slug)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
httpx.TextInterceptor.Intercept(w, r, httpx.ErrNotFound)
|
httpx.TextInterceptor.Intercept(w, r, httpx.ErrNotFound)
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ func (ssh2 *SSH2) handleAuth(ctx ssh.Context, key ssh.PublicKey) bool {
|
||||||
|
|
||||||
// grab the global permissions
|
// grab the global permissions
|
||||||
{
|
{
|
||||||
globalKeys, err := ssh2.Dependencies.Keys.Admin(ctx)
|
globalKeys, err := ssh2.dependencies.Keys.Admin(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
@ -62,7 +62,7 @@ func (ssh2 *SSH2) handleAuth(ctx ssh.Context, key ssh.PublicKey) bool {
|
||||||
|
|
||||||
// grab permissions for each instance
|
// grab permissions for each instance
|
||||||
{
|
{
|
||||||
instances, err := ssh2.Dependencies.Instances.All(ctx)
|
instances, err := ssh2.dependencies.Instances.All(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import (
|
||||||
|
|
||||||
type SSH2 struct {
|
type SSH2 struct {
|
||||||
component.Base
|
component.Base
|
||||||
Dependencies struct {
|
dependencies struct {
|
||||||
SQL *sql.SQL
|
SQL *sql.SQL
|
||||||
Instances *instances.Instances
|
Instances *instances.Instances
|
||||||
Auth *auth.Auth
|
Auth *auth.Auth
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import (
|
||||||
|
|
||||||
type SSHKeys struct {
|
type SSHKeys struct {
|
||||||
component.Base
|
component.Base
|
||||||
Dependencies struct {
|
dependencies struct {
|
||||||
SQL *sql.SQL
|
SQL *sql.SQL
|
||||||
Auth *auth.Auth
|
Auth *auth.Auth
|
||||||
}
|
}
|
||||||
|
|
@ -25,7 +25,7 @@ var (
|
||||||
// Admin returns the set of administrative ssh keys.
|
// Admin returns the set of administrative ssh keys.
|
||||||
// These are ssh keys associated to distillery admin users.
|
// These are ssh keys associated to distillery admin users.
|
||||||
func (k *SSHKeys) Admin(ctx context.Context) (keys []ssh.PublicKey, err error) {
|
func (k *SSHKeys) Admin(ctx context.Context) (keys []ssh.PublicKey, err error) {
|
||||||
users, err := k.Dependencies.Auth.Users(ctx)
|
users, err := k.dependencies.Auth.Users(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import (
|
||||||
|
|
||||||
func (ssh2 *SSHKeys) TableInfo() component.TableInfo {
|
func (ssh2 *SSHKeys) TableInfo() component.TableInfo {
|
||||||
return component.TableInfo{
|
return component.TableInfo{
|
||||||
Model: reflectx.MakeType[models.Keys](),
|
Model: reflectx.TypeFor[models.Keys](),
|
||||||
Name: models.KeysTable,
|
Name: models.KeysTable,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -24,7 +24,7 @@ func (ssh2 *SSHKeys) Keys(ctx context.Context, user string) ([]models.Keys, erro
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the table
|
// get the table
|
||||||
table, err := ssh2.Dependencies.SQL.QueryTable(ctx, ssh2)
|
table, err := ssh2.dependencies.SQL.QueryTable(ctx, ssh2)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -44,7 +44,7 @@ func (ssh2 *SSHKeys) Keys(ctx context.Context, user string) ([]models.Keys, erro
|
||||||
func (ssh2 *SSHKeys) Add(ctx context.Context, user string, comment string, key ssh.PublicKey) error {
|
func (ssh2 *SSHKeys) Add(ctx context.Context, user string, comment string, key ssh.PublicKey) error {
|
||||||
// check that the given user exists
|
// check that the given user exists
|
||||||
{
|
{
|
||||||
_, err := ssh2.Dependencies.Auth.User(ctx, user)
|
_, err := ssh2.dependencies.Auth.User(ctx, user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -76,7 +76,7 @@ func (ssh2 *SSHKeys) Add(ctx context.Context, user string, comment string, key s
|
||||||
mk.SetPublicKey(key)
|
mk.SetPublicKey(key)
|
||||||
|
|
||||||
// get the table
|
// get the table
|
||||||
table, err := ssh2.Dependencies.SQL.QueryTable(ctx, ssh2)
|
table, err := ssh2.dependencies.SQL.QueryTable(ctx, ssh2)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -107,7 +107,7 @@ func (ssh2 *SSHKeys) Remove(ctx context.Context, user string, key ssh.PublicKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
// query the table again
|
// query the table again
|
||||||
table, err := ssh2.Dependencies.SQL.QueryTable(ctx, ssh2)
|
table, err := ssh2.dependencies.SQL.QueryTable(ctx, ssh2)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -118,7 +118,7 @@ func (ssh2 *SSHKeys) Remove(ctx context.Context, user string, key ssh.PublicKey)
|
||||||
|
|
||||||
func (ssh2 *SSHKeys) OnUserDelete(ctx context.Context, user *models.User) error {
|
func (ssh2 *SSHKeys) OnUserDelete(ctx context.Context, user *models.User) error {
|
||||||
// get the table
|
// get the table
|
||||||
table, err := ssh2.Dependencies.SQL.QueryTable(ctx, ssh2)
|
table, err := ssh2.dependencies.SQL.QueryTable(ctx, ssh2)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,29 @@ type Distillery struct {
|
||||||
lifetimeInit sync.Once
|
lifetimeInit sync.Once
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// INIT & EXPORT
|
||||||
|
//
|
||||||
|
|
||||||
|
func (dis *Distillery) init() {
|
||||||
|
dis.lifetimeInit.Do(func() {
|
||||||
|
dis.lifetime.Init = func(c component.Component, s component.Still) {
|
||||||
|
component.Init(c, s)
|
||||||
|
}
|
||||||
|
dis.lifetime.Register = dis.allComponents
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func export[C component.Component](dis *Distillery) C {
|
||||||
|
dis.init()
|
||||||
|
return lifetime.Export[C](&dis.lifetime, dis.Still)
|
||||||
|
}
|
||||||
|
|
||||||
|
func exportAll[C component.Component](dis *Distillery) []C {
|
||||||
|
dis.init()
|
||||||
|
return lifetime.ExportSlice[C](&dis.lifetime, dis.Still)
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// PUBLIC COMPONENT GETTERS
|
// PUBLIC COMPONENT GETTERS
|
||||||
//
|
//
|
||||||
|
|
@ -119,92 +142,87 @@ func (dis *Distillery) Purger() *purger.Purger {
|
||||||
// THESE SHOULD NEVER BE CALLED DIRECTLY
|
// THESE SHOULD NEVER BE CALLED DIRECTLY
|
||||||
//
|
//
|
||||||
|
|
||||||
func (dis *Distillery) allComponents() []initFunc {
|
func (dis *Distillery) allComponents(context *lifetime.RegisterContext[component.Component, component.Still]) {
|
||||||
return []initFunc{
|
lifetime.Place[*docker.Docker](context)
|
||||||
auto[*docker.Docker],
|
lifetime.Place[*binder.Binder](context)
|
||||||
auto[*binder.Binder],
|
lifetime.Place[*web.Web](context)
|
||||||
auto[*web.Web],
|
|
||||||
|
|
||||||
manual(func(ts *triplestore.Triplestore) {
|
lifetime.Register(context, func(ts *triplestore.Triplestore, _ component.Still) {
|
||||||
ts.BaseURL = "http://" + dis.Upstream.TriplestoreAddr()
|
ts.BaseURL = "http://" + dis.Upstream.TriplestoreAddr()
|
||||||
ts.PollInterval = time.Second
|
ts.PollInterval = time.Second
|
||||||
}),
|
})
|
||||||
|
|
||||||
manual(func(sql *sql.SQL) {
|
lifetime.Register(context, func(sql *sql.SQL, _ component.Still) {
|
||||||
sql.ServerURL = dis.Upstream.SQLAddr()
|
sql.ServerURL = dis.Upstream.SQLAddr()
|
||||||
sql.PollInterval = time.Second
|
sql.PollInterval = time.Second
|
||||||
}),
|
})
|
||||||
auto[*sql.LockTable],
|
lifetime.Place[*sql.LockTable](context)
|
||||||
auto[*sql.InstanceTable],
|
lifetime.Place[*sql.InstanceTable](context)
|
||||||
|
|
||||||
manual(func(s *solr.Solr) {
|
lifetime.Register(context, func(s *solr.Solr, _ component.Still) {
|
||||||
s.BaseURL = dis.Upstream.SolrAddr()
|
s.BaseURL = dis.Upstream.SolrAddr()
|
||||||
s.PollInterval = time.Second
|
s.PollInterval = time.Second
|
||||||
}),
|
})
|
||||||
|
|
||||||
// auth
|
// auth
|
||||||
auto[*auth.Auth],
|
lifetime.Place[*auth.Auth](context)
|
||||||
auto[*policy.Policy],
|
lifetime.Place[*policy.Policy](context)
|
||||||
auto[*panel.UserPanel],
|
lifetime.Place[*panel.UserPanel](context)
|
||||||
auto[*next.Next],
|
lifetime.Place[*next.Next](context)
|
||||||
auto[*tokens.Tokens],
|
lifetime.Place[*tokens.Tokens](context)
|
||||||
|
|
||||||
//scopes
|
//scopes
|
||||||
auto[*scopes.Never],
|
lifetime.Place[*scopes.Never](context)
|
||||||
auto[*scopes.UserLoggedIn],
|
lifetime.Place[*scopes.UserLoggedIn](context)
|
||||||
auto[*scopes.AdminLoggedIn],
|
lifetime.Place[*scopes.AdminLoggedIn](context)
|
||||||
auto[*scopes.ListInstancesScope],
|
lifetime.Place[*scopes.ListInstancesScope](context)
|
||||||
auto[*scopes.ListNewsScope],
|
lifetime.Place[*scopes.ListNewsScope](context)
|
||||||
auto[*scopes.ResolverScope],
|
lifetime.Place[*scopes.ResolverScope](context)
|
||||||
|
|
||||||
// instances
|
// instances
|
||||||
auto[*instances.Instances],
|
lifetime.Place[*instances.Instances](context)
|
||||||
auto[*meta.Meta],
|
lifetime.Place[*meta.Meta](context)
|
||||||
auto[*malt.Malt],
|
lifetime.Place[*malt.Malt](context)
|
||||||
auto[*provision.Provision],
|
lifetime.Place[*provision.Provision](context)
|
||||||
|
|
||||||
// Purger
|
// Purger
|
||||||
auto[*purger.Purger],
|
lifetime.Place[*purger.Purger](context)
|
||||||
|
|
||||||
// Snapshots
|
// Snapshots
|
||||||
auto[*exporter.Exporter],
|
lifetime.Place[*exporter.Exporter](context)
|
||||||
auto[*logger.Logger],
|
lifetime.Place[*logger.Logger](context)
|
||||||
auto[*exporter.Config],
|
lifetime.Place[*exporter.Config](context)
|
||||||
auto[*exporter.Bookkeeping],
|
lifetime.Place[*exporter.Bookkeeping](context)
|
||||||
auto[*exporter.Filesystem],
|
lifetime.Place[*exporter.Filesystem](context)
|
||||||
auto[*exporter.Pathbuilders],
|
lifetime.Place[*exporter.Pathbuilders](context)
|
||||||
|
|
||||||
// ssh server
|
// ssh server
|
||||||
auto[*ssh2.SSH2],
|
lifetime.Place[*ssh2.SSH2](context)
|
||||||
auto[*sshkeys.SSHKeys],
|
lifetime.Place[*sshkeys.SSHKeys](context)
|
||||||
|
|
||||||
// Control server
|
// Control server
|
||||||
auto[*server.Server],
|
lifetime.Place[*server.Server](context)
|
||||||
|
|
||||||
auto[*home.Home],
|
lifetime.Place[*home.Home](context)
|
||||||
auto[*list.ListInstances],
|
lifetime.Place[*list.ListInstances](context)
|
||||||
manual(func(resolver *resolver.Resolver) {
|
lifetime.Register(context, func(resolver *resolver.Resolver, _ component.Still) {
|
||||||
resolver.RefreshInterval = time.Minute
|
resolver.RefreshInterval = time.Minute
|
||||||
}),
|
})
|
||||||
manual(func(admin *admin.Admin) {
|
lifetime.Place[*admin.Admin](context) // TODO: Remove analytics
|
||||||
admin.Analytics = &dis.lifetime.Analytics
|
lifetime.Place[*socket.Sockets](context)
|
||||||
}),
|
lifetime.Place[*legal.Legal](context)
|
||||||
auto[*socket.Sockets],
|
lifetime.Place[*news.News](context)
|
||||||
auto[*legal.Legal],
|
|
||||||
auto[*news.News],
|
|
||||||
|
|
||||||
auto[*assets.Static],
|
lifetime.Place[*assets.Static](context)
|
||||||
auto[*logo.Logo],
|
lifetime.Place[*logo.Logo](context)
|
||||||
auto[*templating.Templating],
|
lifetime.Place[*templating.Templating](context)
|
||||||
|
|
||||||
// Cron
|
// Cron
|
||||||
auto[*cron.Cron],
|
lifetime.Place[*cron.Cron](context)
|
||||||
|
|
||||||
// API
|
// API
|
||||||
auto[*api.API],
|
lifetime.Place[*api.API](context)
|
||||||
auto[*list.API],
|
lifetime.Place[*list.API](context)
|
||||||
auto[*list.API],
|
lifetime.Place[*news.API](context)
|
||||||
auto[*news.API],
|
lifetime.Place[*resolver.API](context)
|
||||||
auto[*resolver.API],
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,7 @@ func (server *Server) prepare() error {
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// start the actual server
|
// start the actual server
|
||||||
io := stream.NewIOStream(&lb, nil, ir, 0)
|
io := stream.NewIOStream(&lb, nil, ir)
|
||||||
err := server.Executor.Spawn(server.c, io, serverPHP)
|
err := server.Executor.Spawn(server.c, io, serverPHP)
|
||||||
server.err.Set(ServerError{errClosed, err})
|
server.err.Set(ServerError{errClosed, err})
|
||||||
}()
|
}()
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ import (
|
||||||
// Barrel provides access to the underlying Barrel
|
// Barrel provides access to the underlying Barrel
|
||||||
type Barrel struct {
|
type Barrel struct {
|
||||||
ingredient.Base
|
ingredient.Base
|
||||||
Dependencies struct {
|
dependencies struct {
|
||||||
Locker *locker.Locker
|
Locker *locker.Locker
|
||||||
MStore *mstore.MStore
|
MStore *mstore.MStore
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,10 +17,10 @@ import (
|
||||||
//
|
//
|
||||||
// It also logs the current time into the metadata belonging to this instance.
|
// It also logs the current time into the metadata belonging to this instance.
|
||||||
func (barrel *Barrel) Build(ctx context.Context, progress io.Writer, start bool) error {
|
func (barrel *Barrel) Build(ctx context.Context, progress io.Writer, start bool) error {
|
||||||
if !barrel.Dependencies.Locker.TryLock(ctx) {
|
if !barrel.dependencies.Locker.TryLock(ctx) {
|
||||||
return locker.Locked
|
return locker.Locked
|
||||||
}
|
}
|
||||||
defer barrel.Dependencies.Locker.Unlock(ctx)
|
defer barrel.dependencies.Locker.Unlock(ctx)
|
||||||
|
|
||||||
stack := barrel.Stack()
|
stack := barrel.Stack()
|
||||||
|
|
||||||
|
|
@ -48,7 +48,7 @@ func (barrel *Barrel) Build(ctx context.Context, progress io.Writer, start bool)
|
||||||
var lastRebuild = mstore.For[int64]("lastRebuild")
|
var lastRebuild = mstore.For[int64]("lastRebuild")
|
||||||
|
|
||||||
func (barrel Barrel) LastRebuild(ctx context.Context) (t time.Time, err error) {
|
func (barrel Barrel) LastRebuild(ctx context.Context) (t time.Time, err error) {
|
||||||
epoch, err := lastRebuild.Get(ctx, barrel.Dependencies.MStore)
|
epoch, err := lastRebuild.Get(ctx, barrel.dependencies.MStore)
|
||||||
if err == meta.ErrMetadatumNotSet {
|
if err == meta.ErrMetadatumNotSet {
|
||||||
return t, nil
|
return t, nil
|
||||||
}
|
}
|
||||||
|
|
@ -61,17 +61,17 @@ func (barrel Barrel) LastRebuild(ctx context.Context) (t time.Time, err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (barrel *Barrel) setLastRebuild(ctx context.Context) error {
|
func (barrel *Barrel) setLastRebuild(ctx context.Context) error {
|
||||||
return lastRebuild.Set(ctx, barrel.Dependencies.MStore, time.Now().Unix())
|
return lastRebuild.Set(ctx, barrel.dependencies.MStore, time.Now().Unix())
|
||||||
}
|
}
|
||||||
|
|
||||||
type LastRebuildFetcher struct {
|
type LastRebuildFetcher struct {
|
||||||
ingredient.Base
|
ingredient.Base
|
||||||
Dependencies struct {
|
dependencies struct {
|
||||||
Barrel *Barrel
|
Barrel *Barrel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lbr *LastRebuildFetcher) Fetch(ctx context.Context, flags ingredient.FetcherFlags, info *status.WissKI) (err error) {
|
func (lbr *LastRebuildFetcher) Fetch(ctx context.Context, flags ingredient.FetcherFlags, info *status.WissKI) (err error) {
|
||||||
info.LastRebuild, _ = lbr.Dependencies.Barrel.LastRebuild(ctx)
|
info.LastRebuild, _ = lbr.dependencies.Barrel.LastRebuild(ctx)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ import (
|
||||||
// Drush implements commands related to drush
|
// Drush implements commands related to drush
|
||||||
type Composer struct {
|
type Composer struct {
|
||||||
ingredient.Base
|
ingredient.Base
|
||||||
Dependencies struct {
|
dependencies struct {
|
||||||
Barrel *barrel.Barrel
|
Barrel *barrel.Barrel
|
||||||
MStore *mstore.MStore
|
MStore *mstore.MStore
|
||||||
Drush *drush.Drush
|
Drush *drush.Drush
|
||||||
|
|
@ -35,7 +35,7 @@ func (composer *Composer) ExecWissKI(ctx context.Context, progress io.Writer, co
|
||||||
}
|
}
|
||||||
|
|
||||||
func (composer *Composer) exec(ctx context.Context, progress io.Writer, command ...string) error {
|
func (composer *Composer) exec(ctx context.Context, progress io.Writer, command ...string) error {
|
||||||
if err := composer.Dependencies.Barrel.ShellScript(ctx, stream.NonInteractive(progress), append([]string{"composer", "--no-interaction"}, command...)...); err != nil {
|
if err := composer.dependencies.Barrel.ShellScript(ctx, stream.NonInteractive(progress), append([]string{"composer", "--no-interaction"}, command...)...); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -44,7 +44,7 @@ func (composer *Composer) exec(ctx context.Context, progress io.Writer, command
|
||||||
// FixPermissions fixes the permissions of the sites directory.
|
// FixPermissions fixes the permissions of the sites directory.
|
||||||
// This needs to be run after every installation of a composer module.
|
// This needs to be run after every installation of a composer module.
|
||||||
func (composer *Composer) FixPermission(ctx context.Context, progress io.Writer) error {
|
func (composer *Composer) FixPermission(ctx context.Context, progress io.Writer) error {
|
||||||
composer.Dependencies.Barrel.ShellScript(ctx, stream.NonInteractive(progress), "chmod", "-R", "u+w", barrel.SitesDirectory)
|
composer.dependencies.Barrel.ShellScript(ctx, stream.NonInteractive(progress), "chmod", "-R", "u+w", barrel.SitesDirectory)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ func (composer *Composer) Update(ctx context.Context, progress io.Writer) (err e
|
||||||
|
|
||||||
logging.LogMessage(progress, "Installing database updates")
|
logging.LogMessage(progress, "Installing database updates")
|
||||||
{
|
{
|
||||||
err := composer.Dependencies.Drush.Exec(ctx, progress, "-y", "updatedb")
|
err := composer.dependencies.Drush.Exec(ctx, progress, "-y", "updatedb")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -56,7 +56,7 @@ func (composer *Composer) Update(ctx context.Context, progress io.Writer) (err e
|
||||||
const lastUpdate = mstore.For[int64]("lastUpdate")
|
const lastUpdate = mstore.For[int64]("lastUpdate")
|
||||||
|
|
||||||
func (drush *Composer) LastUpdate(ctx context.Context) (t time.Time, err error) {
|
func (drush *Composer) LastUpdate(ctx context.Context) (t time.Time, err error) {
|
||||||
epoch, err := lastUpdate.Get(ctx, drush.Dependencies.MStore)
|
epoch, err := lastUpdate.Get(ctx, drush.dependencies.MStore)
|
||||||
if err == meta.ErrMetadatumNotSet {
|
if err == meta.ErrMetadatumNotSet {
|
||||||
return t, nil
|
return t, nil
|
||||||
}
|
}
|
||||||
|
|
@ -69,12 +69,12 @@ func (drush *Composer) LastUpdate(ctx context.Context) (t time.Time, err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (drush *Composer) setLastUpdate(ctx context.Context) error {
|
func (drush *Composer) setLastUpdate(ctx context.Context) error {
|
||||||
return lastUpdate.Set(ctx, drush.Dependencies.MStore, time.Now().Unix())
|
return lastUpdate.Set(ctx, drush.dependencies.MStore, time.Now().Unix())
|
||||||
}
|
}
|
||||||
|
|
||||||
type LastUpdateFetcher struct {
|
type LastUpdateFetcher struct {
|
||||||
ingredient.Base
|
ingredient.Base
|
||||||
Dependencies struct {
|
dependencies struct {
|
||||||
Composer *Composer
|
Composer *Composer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -84,6 +84,6 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
func (lbr *LastUpdateFetcher) Fetch(flags ingredient.FetcherFlags, info *status.WissKI) (err error) {
|
func (lbr *LastUpdateFetcher) Fetch(flags ingredient.FetcherFlags, info *status.WissKI) (err error) {
|
||||||
info.LastUpdate, err = lbr.Dependencies.Composer.LastUpdate(flags.Context)
|
info.LastUpdate, err = lbr.dependencies.Composer.LastUpdate(flags.Context)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ func (drush *Drush) Cron(ctx context.Context, progress io.Writer) error {
|
||||||
|
|
||||||
func (drush *Drush) LastCron(ctx context.Context, server *phpx.Server) (t time.Time, err error) {
|
func (drush *Drush) LastCron(ctx context.Context, server *phpx.Server) (t time.Time, err error) {
|
||||||
var timestamp int64
|
var timestamp int64
|
||||||
err = drush.Dependencies.PHP.EvalCode(ctx, server, ×tamp, `return \Drupal::state()->get('system.cron_last');`)
|
err = drush.dependencies.PHP.EvalCode(ctx, server, ×tamp, `return \Drupal::state()->get('system.cron_last');`)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -41,7 +41,7 @@ func (drush *Drush) LastCron(ctx context.Context, server *phpx.Server) (t time.T
|
||||||
|
|
||||||
type LastCronFetcher struct {
|
type LastCronFetcher struct {
|
||||||
ingredient.Base
|
ingredient.Base
|
||||||
Dependencies struct {
|
dependencies struct {
|
||||||
Drush *Drush
|
Drush *Drush
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -55,6 +55,6 @@ func (lbr *LastCronFetcher) Fetch(flags ingredient.FetcherFlags, info *status.Wi
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
info.LastRebuild, _ = lbr.Dependencies.Drush.LastCron(flags.Context, flags.Server)
|
info.LastRebuild, _ = lbr.dependencies.Drush.LastCron(flags.Context, flags.Server)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ import (
|
||||||
// Drush implements commands related to drush
|
// Drush implements commands related to drush
|
||||||
type Drush struct {
|
type Drush struct {
|
||||||
ingredient.Base
|
ingredient.Base
|
||||||
Dependencies struct {
|
dependencies struct {
|
||||||
Barrel *barrel.Barrel
|
Barrel *barrel.Barrel
|
||||||
PHP *php.PHP
|
PHP *php.PHP
|
||||||
}
|
}
|
||||||
|
|
@ -26,5 +26,5 @@ func (drush *Drush) Enable(ctx context.Context, progress io.Writer, modules ...s
|
||||||
|
|
||||||
func (drush *Drush) Exec(ctx context.Context, progress io.Writer, command ...string) error {
|
func (drush *Drush) Exec(ctx context.Context, progress io.Writer, command ...string) error {
|
||||||
script := append([]string{"drush"}, command...)
|
script := append([]string{"drush"}, command...)
|
||||||
return drush.Dependencies.Barrel.ShellScript(ctx, stream.NonInteractive(progress), script...)
|
return drush.dependencies.Barrel.ShellScript(ctx, stream.NonInteractive(progress), script...)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ func (manager *Manager) installModules(ctx context.Context, progress io.Writer,
|
||||||
return logging.LogOperation(func() error {
|
return logging.LogOperation(func() error {
|
||||||
for _, spec := range modules {
|
for _, spec := range modules {
|
||||||
logging.LogMessage(progress, fmt.Sprintf("Installing %q", spec))
|
logging.LogMessage(progress, fmt.Sprintf("Installing %q", spec))
|
||||||
err := manager.Dependencies.Composer.Install(ctx, progress, spec)
|
err := manager.dependencies.Composer.Install(ctx, progress, spec)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -67,7 +67,7 @@ func (manager *Manager) installModules(ctx context.Context, progress io.Writer,
|
||||||
if enable {
|
if enable {
|
||||||
name := composer.ModuleName(spec)
|
name := composer.ModuleName(spec)
|
||||||
logging.LogMessage(progress, fmt.Sprintf("Enabling %q (from spec %q)", name, spec))
|
logging.LogMessage(progress, fmt.Sprintf("Enabling %q (from spec %q)", name, spec))
|
||||||
err := manager.Dependencies.Drush.Enable(ctx, progress, name)
|
err := manager.dependencies.Drush.Enable(ctx, progress, name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -90,7 +90,7 @@ func (manager *Manager) applyDrupal(ctx context.Context, progress io.Writer, dru
|
||||||
{"chmod", "666", "web/sites/default/*settings.php"},
|
{"chmod", "666", "web/sites/default/*settings.php"},
|
||||||
{"chmod", "666", "web/sites/default/*services.php"},
|
{"chmod", "666", "web/sites/default/*services.php"},
|
||||||
} {
|
} {
|
||||||
err := manager.Dependencies.Barrel.ShellScript(ctx, stream.NonInteractive(progress), script...)
|
err := manager.dependencies.Barrel.ShellScript(ctx, stream.NonInteractive(progress), script...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -105,7 +105,7 @@ func (manager *Manager) applyDrupal(ctx context.Context, progress io.Writer, dru
|
||||||
{"chmod", "644", "web/sites/default/*settings.php"},
|
{"chmod", "644", "web/sites/default/*settings.php"},
|
||||||
{"chmod", "644", "web/sites/default/*services.php"},
|
{"chmod", "644", "web/sites/default/*services.php"},
|
||||||
} {
|
} {
|
||||||
manager.Dependencies.Barrel.ShellScript(ctx, stream.NonInteractive(progress), script...)
|
manager.dependencies.Barrel.ShellScript(ctx, stream.NonInteractive(progress), script...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
@ -121,21 +121,21 @@ func (manager *Manager) applyDrupal(ctx context.Context, progress io.Writer, dru
|
||||||
}
|
}
|
||||||
args = append(args, "--update-with-dependencies", "--no-update")
|
args = append(args, "--update-with-dependencies", "--no-update")
|
||||||
|
|
||||||
if err := manager.Dependencies.Composer.Install(ctx, progress, args...); err != nil {
|
if err := manager.dependencies.Composer.Install(ctx, progress, args...); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
logging.LogMessage(progress, "Running composer update")
|
logging.LogMessage(progress, "Running composer update")
|
||||||
{
|
{
|
||||||
if err := manager.Dependencies.Composer.Exec(ctx, progress, "update"); err != nil {
|
if err := manager.dependencies.Composer.Exec(ctx, progress, "update"); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
logging.LogMessage(progress, "Performing database updates (if any)")
|
logging.LogMessage(progress, "Performing database updates (if any)")
|
||||||
{
|
{
|
||||||
if err := manager.Dependencies.Drush.Exec(ctx, progress, "updatedb", "--yes"); err != nil {
|
if err := manager.dependencies.Drush.Exec(ctx, progress, "updatedb", "--yes"); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -156,7 +156,7 @@ func (manager *Manager) applyWissKI(ctx context.Context, progress io.Writer, wis
|
||||||
spec += ":" + wisski
|
spec += ":" + wisski
|
||||||
}
|
}
|
||||||
|
|
||||||
err := manager.Dependencies.Composer.Install(ctx, progress, spec)
|
err := manager.dependencies.Composer.Install(ctx, progress, spec)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -165,27 +165,27 @@ func (manager *Manager) applyWissKI(ctx context.Context, progress io.Writer, wis
|
||||||
// install dependencies in the WissKI directory
|
// install dependencies in the WissKI directory
|
||||||
logging.LogMessage(progress, "Installing WissKI Dependencies")
|
logging.LogMessage(progress, "Installing WissKI Dependencies")
|
||||||
{
|
{
|
||||||
if err := manager.Dependencies.Composer.ExecWissKI(ctx, progress, "install"); err != nil {
|
if err := manager.dependencies.Composer.ExecWissKI(ctx, progress, "install"); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
logging.LogMessage(progress, "Enable Wisski modules")
|
logging.LogMessage(progress, "Enable Wisski modules")
|
||||||
{
|
{
|
||||||
if err := manager.Dependencies.Drush.Enable(ctx, progress,
|
if err := manager.dependencies.Drush.Enable(ctx, progress,
|
||||||
"wisski_core", "wisski_linkblock", "wisski_pathbuilder", "wisski_adapter_sparql11_pb", "wisski_salz",
|
"wisski_core", "wisski_linkblock", "wisski_pathbuilder", "wisski_adapter_sparql11_pb", "wisski_salz",
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := manager.Dependencies.Composer.FixPermission(ctx, progress); err != nil {
|
if err := manager.dependencies.Composer.FixPermission(ctx, progress); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
logging.LogMessage(progress, "Performing database updates (if any)")
|
logging.LogMessage(progress, "Performing database updates (if any)")
|
||||||
{
|
{
|
||||||
if err := manager.Dependencies.Drush.Exec(ctx, progress, "updatedb", "--yes"); err != nil {
|
if err := manager.dependencies.Drush.Exec(ctx, progress, "updatedb", "--yes"); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ import (
|
||||||
// Manager manages a profile applied to specific WissKI instances.
|
// Manager manages a profile applied to specific WissKI instances.
|
||||||
type Manager struct {
|
type Manager struct {
|
||||||
ingredient.Base
|
ingredient.Base
|
||||||
Dependencies struct {
|
dependencies struct {
|
||||||
Barrel *barrel.Barrel
|
Barrel *barrel.Barrel
|
||||||
Bookkeeping *bookkeeping.Bookkeeping
|
Bookkeeping *bookkeeping.Bookkeeping
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,14 +23,14 @@ import (
|
||||||
// Provision applies defaults to flags, to ensure some values are set
|
// Provision applies defaults to flags, to ensure some values are set
|
||||||
func (manager *Manager) Provision(ctx context.Context, progress io.Writer, system models.System, flags Profile) error {
|
func (manager *Manager) Provision(ctx context.Context, progress io.Writer, system models.System, flags Profile) error {
|
||||||
// Force building and applying the system!
|
// Force building and applying the system!
|
||||||
if err := manager.Dependencies.SystemManager.Apply(ctx, progress, system, false); err != nil {
|
if err := manager.dependencies.SystemManager.Apply(ctx, progress, system, false); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the composer directory!
|
// Create the composer directory!
|
||||||
logging.LogMessage(progress, "Creating required directories")
|
logging.LogMessage(progress, "Creating required directories")
|
||||||
{
|
{
|
||||||
code, err := manager.Dependencies.Barrel.Stack().Run(ctx, stream.FromNil(), component.RunFlags{Detach: true, AutoRemove: true}, "barrel", "sudo", "-u", "www-data", "mkdir", "-p", barrel.ComposerDirectory)
|
code, err := manager.dependencies.Barrel.Stack().Run(ctx, stream.FromNil(), component.RunFlags{Detach: true, AutoRemove: true}, "barrel", "sudo", "-u", "www-data", "mkdir", "-p", barrel.ComposerDirectory)
|
||||||
if code != 0 {
|
if code != 0 {
|
||||||
err = barrel.ExitError(code)
|
err = barrel.ExitError(code)
|
||||||
}
|
}
|
||||||
|
|
@ -40,7 +40,7 @@ func (manager *Manager) Provision(ctx context.Context, progress io.Writer, syste
|
||||||
}
|
}
|
||||||
|
|
||||||
// start the container, and have it do nothing!
|
// start the container, and have it do nothing!
|
||||||
code, err := manager.Dependencies.Barrel.Stack().Run(ctx, stream.FromNil(), component.RunFlags{Detach: true, AutoRemove: true}, "barrel", "tail", "-f", "/dev/null")
|
code, err := manager.dependencies.Barrel.Stack().Run(ctx, stream.FromNil(), component.RunFlags{Detach: true, AutoRemove: true}, "barrel", "tail", "-f", "/dev/null")
|
||||||
if code != 0 {
|
if code != 0 {
|
||||||
err = barrel.ExitError(code)
|
err = barrel.ExitError(code)
|
||||||
}
|
}
|
||||||
|
|
@ -54,7 +54,7 @@ func (manager *Manager) Provision(ctx context.Context, progress io.Writer, syste
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
// stop the container (even if the context was cancelled)
|
// stop the container (even if the context was cancelled)
|
||||||
manager.Dependencies.Barrel.Stack().DownAll(anyways, progress)
|
manager.dependencies.Barrel.Stack().DownAll(anyways, progress)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// Apply the defaults to the flags
|
// Apply the defaults to the flags
|
||||||
|
|
@ -80,7 +80,7 @@ func (provision *Manager) bootstrap(ctx context.Context, progress io.Writer, fla
|
||||||
if flags.Drupal != "" {
|
if flags.Drupal != "" {
|
||||||
drupal += ":" + flags.Drupal
|
drupal += ":" + flags.Drupal
|
||||||
}
|
}
|
||||||
err := provision.Dependencies.Composer.Exec(ctx, progress, "create-project", drupal, ".")
|
err := provision.dependencies.Composer.Exec(ctx, progress, "create-project", drupal, ".")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -89,7 +89,7 @@ func (provision *Manager) bootstrap(ctx context.Context, progress io.Writer, fla
|
||||||
logging.LogMessage(progress, "Configuring Composer")
|
logging.LogMessage(progress, "Configuring Composer")
|
||||||
{
|
{
|
||||||
// needed for composer > 2.2
|
// needed for composer > 2.2
|
||||||
err := provision.Dependencies.Composer.Exec(ctx, progress, "config", "allow-plugins", "true")
|
err := provision.dependencies.Composer.Exec(ctx, progress, "config", "allow-plugins", "true")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -98,7 +98,7 @@ func (provision *Manager) bootstrap(ctx context.Context, progress io.Writer, fla
|
||||||
logging.LogMessage(progress, "Installing drush")
|
logging.LogMessage(progress, "Installing drush")
|
||||||
{
|
{
|
||||||
for _, v := range drushVariants {
|
for _, v := range drushVariants {
|
||||||
err := provision.Dependencies.Composer.TryInstall(ctx, progress, v)
|
err := provision.dependencies.Composer.TryInstall(ctx, progress, v)
|
||||||
if err == composer.ErrNotInstalled {
|
if err == composer.ErrNotInstalled {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
@ -115,7 +115,7 @@ func (provision *Manager) bootstrap(ctx context.Context, progress io.Writer, fla
|
||||||
// Here we need to use the username, password and database creds we made above.
|
// Here we need to use the username, password and database creds we made above.
|
||||||
logging.LogMessage(progress, "Running Drupal installation scripts")
|
logging.LogMessage(progress, "Running Drupal installation scripts")
|
||||||
{
|
{
|
||||||
if err := provision.Dependencies.Drush.Exec(
|
if err := provision.dependencies.Drush.Exec(
|
||||||
ctx, progress,
|
ctx, progress,
|
||||||
"site-install",
|
"site-install",
|
||||||
"standard", "--yes", "--site-name="+provision.Domain(),
|
"standard", "--yes", "--site-name="+provision.Domain(),
|
||||||
|
|
@ -125,7 +125,7 @@ func (provision *Manager) bootstrap(ctx context.Context, progress io.Writer, fla
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := provision.Dependencies.Composer.FixPermission(ctx, progress); err != nil {
|
if err := provision.dependencies.Composer.FixPermission(ctx, progress); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -133,7 +133,7 @@ func (provision *Manager) bootstrap(ctx context.Context, progress io.Writer, fla
|
||||||
// Create directory for ontologies
|
// Create directory for ontologies
|
||||||
logging.LogMessage(progress, fmt.Sprintf("Creating %q", barrel.OntologyDirectory))
|
logging.LogMessage(progress, fmt.Sprintf("Creating %q", barrel.OntologyDirectory))
|
||||||
{
|
{
|
||||||
if err := provision.Dependencies.Barrel.ShellScript(ctx, stream.NonInteractive(progress), "mkdir", "-p", barrel.OntologyDirectory); err != nil {
|
if err := provision.dependencies.Barrel.ShellScript(ctx, stream.NonInteractive(progress), "mkdir", "-p", barrel.OntologyDirectory); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -158,7 +158,7 @@ func (provision *Manager) bootstrap(ctx context.Context, progress io.Writer, fla
|
||||||
// create the default adapter
|
// create the default adapter
|
||||||
logging.LogMessage(progress, "Creating default adapter")
|
logging.LogMessage(progress, "Creating default adapter")
|
||||||
{
|
{
|
||||||
if err := provision.Dependencies.Adapters.CreateDistilleryAdapter(ctx, nil, extras.DistilleryAdapter{
|
if err := provision.dependencies.Adapters.CreateDistilleryAdapter(ctx, nil, extras.DistilleryAdapter{
|
||||||
Label: "Default WissKI Distillery Adapter",
|
Label: "Default WissKI Distillery Adapter",
|
||||||
MachineName: "default",
|
MachineName: "default",
|
||||||
Description: "Default Adapter for " + provision.Domain(),
|
Description: "Default Adapter for " + provision.Domain(),
|
||||||
|
|
@ -173,14 +173,14 @@ func (provision *Manager) bootstrap(ctx context.Context, progress io.Writer, fla
|
||||||
|
|
||||||
logging.LogMessage(progress, "Updating TRUSTED_HOST_PATTERNS in settings.php")
|
logging.LogMessage(progress, "Updating TRUSTED_HOST_PATTERNS in settings.php")
|
||||||
{
|
{
|
||||||
if err := provision.Dependencies.Settings.SetTrustedDomain(ctx, nil, provision.Domain()); err != nil {
|
if err := provision.dependencies.Settings.SetTrustedDomain(ctx, nil, provision.Domain()); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
logging.LogMessage(progress, "Running initial cron")
|
logging.LogMessage(progress, "Running initial cron")
|
||||||
{
|
{
|
||||||
if err := provision.Dependencies.Drush.Exec(ctx, progress, "core-cron"); err != nil {
|
if err := provision.dependencies.Drush.Exec(ctx, progress, "core-cron"); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ func (barrel *Barrel) Running(ctx context.Context) (bool, error) {
|
||||||
|
|
||||||
type RunningFetcher struct {
|
type RunningFetcher struct {
|
||||||
ingredient.Base
|
ingredient.Base
|
||||||
Dependencies struct {
|
dependencies struct {
|
||||||
Barrel *Barrel
|
Barrel *Barrel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -28,6 +28,6 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
func (rf *RunningFetcher) Fetch(flags ingredient.FetcherFlags, info *status.WissKI) (err error) {
|
func (rf *RunningFetcher) Fetch(flags ingredient.FetcherFlags, info *status.WissKI) (err error) {
|
||||||
info.Running, err = rf.Dependencies.Barrel.Running(flags.Context)
|
info.Running, err = rf.dependencies.Barrel.Running(flags.Context)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ import (
|
||||||
|
|
||||||
type SSH struct {
|
type SSH struct {
|
||||||
ingredient.Base
|
ingredient.Base
|
||||||
Dependencies struct {
|
dependencies struct {
|
||||||
Barrel *barrel.Barrel
|
Barrel *barrel.Barrel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ import (
|
||||||
// SystemManager applies a specific system configuration
|
// SystemManager applies a specific system configuration
|
||||||
type SystemManager struct {
|
type SystemManager struct {
|
||||||
ingredient.Base
|
ingredient.Base
|
||||||
Dependencies struct {
|
dependencies struct {
|
||||||
Barrel *barrel.Barrel
|
Barrel *barrel.Barrel
|
||||||
Bookkeeping *bookkeeping.Bookkeeping
|
Bookkeeping *bookkeeping.Bookkeeping
|
||||||
Settings *extras.Settings
|
Settings *extras.Settings
|
||||||
|
|
@ -28,12 +28,12 @@ func (smanager *SystemManager) Apply(ctx context.Context, progress io.Writer, sy
|
||||||
smanager.Instance.System = system
|
smanager.Instance.System = system
|
||||||
|
|
||||||
// save in bookkeeping
|
// save in bookkeeping
|
||||||
if err := smanager.Dependencies.Bookkeeping.Save(ctx); err != nil {
|
if err := smanager.dependencies.Bookkeeping.Save(ctx); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Apply Content-Security-Policy!
|
// TODO: Apply Content-Security-Policy!
|
||||||
|
|
||||||
// and rebuild
|
// and rebuild
|
||||||
return smanager.Dependencies.Barrel.Build(ctx, progress, start)
|
return smanager.dependencies.Barrel.Build(ctx, progress, start)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,19 +10,16 @@ import (
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/wisski/ingredient"
|
"github.com/FAU-CDI/wisski-distillery/internal/wisski/ingredient"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/wisski/ingredient/php"
|
"github.com/FAU-CDI/wisski-distillery/internal/wisski/ingredient/php"
|
||||||
"github.com/rs/zerolog"
|
"github.com/rs/zerolog"
|
||||||
"github.com/tkw1536/pkglib/lifetime"
|
|
||||||
"github.com/tkw1536/pkglib/sema"
|
"github.com/tkw1536/pkglib/sema"
|
||||||
"golang.org/x/sync/errgroup"
|
"golang.org/x/sync/errgroup"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Info struct {
|
type Info struct {
|
||||||
ingredient.Base
|
ingredient.Base
|
||||||
Dependencies struct {
|
dependencies struct {
|
||||||
PHP *php.PHP
|
PHP *php.PHP
|
||||||
Fetchers []ingredient.WissKIFetcher
|
Fetchers []ingredient.WissKIFetcher
|
||||||
}
|
}
|
||||||
|
|
||||||
Analytics *lifetime.Analytics
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
@ -45,7 +42,7 @@ func (wisski *Info) Information(ctx context.Context, quick bool) (info status.Wi
|
||||||
Limit: 5,
|
Limit: 5,
|
||||||
New: func() *phpx.Server {
|
New: func() *phpx.Server {
|
||||||
atomic.AddUint64(&serversUsed, 1)
|
atomic.AddUint64(&serversUsed, 1)
|
||||||
return wisski.Dependencies.PHP.NewServer()
|
return wisski.dependencies.PHP.NewServer()
|
||||||
},
|
},
|
||||||
Discard: func(s *phpx.Server) {
|
Discard: func(s *phpx.Server) {
|
||||||
s.Close()
|
s.Close()
|
||||||
|
|
@ -55,7 +52,7 @@ func (wisski *Info) Information(ctx context.Context, quick bool) (info status.Wi
|
||||||
|
|
||||||
// setup a dictionary to record data about how long each operation took.
|
// setup a dictionary to record data about how long each operation took.
|
||||||
// we use a slice as opposed to a map to avoid having to mutex!
|
// we use a slice as opposed to a map to avoid having to mutex!
|
||||||
fetcherTimes := make([]time.Duration, len(wisski.Dependencies.Fetchers))
|
fetcherTimes := make([]time.Duration, len(wisski.dependencies.Fetchers))
|
||||||
recordTime := func(i int) func() {
|
recordTime := func(i int) func() {
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
return func() {
|
return func() {
|
||||||
|
|
@ -66,7 +63,7 @@ func (wisski *Info) Information(ctx context.Context, quick bool) (info status.Wi
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
{
|
{
|
||||||
var group errgroup.Group
|
var group errgroup.Group
|
||||||
for i, fetcher := range wisski.Dependencies.Fetchers {
|
for i, fetcher := range wisski.dependencies.Fetchers {
|
||||||
fetcher, flags, i := fetcher, flags, i
|
fetcher, flags, i := fetcher, flags, i
|
||||||
group.Go(func() error {
|
group.Go(func() error {
|
||||||
// quick: don't need to create servers
|
// quick: don't need to create servers
|
||||||
|
|
@ -93,7 +90,7 @@ func (wisski *Info) Information(ctx context.Context, quick bool) (info status.Wi
|
||||||
|
|
||||||
// get a map of how long each fetcher took
|
// get a map of how long each fetcher took
|
||||||
times := zerolog.Dict()
|
times := zerolog.Dict()
|
||||||
for i, fetcher := range wisski.Dependencies.Fetchers {
|
for i, fetcher := range wisski.dependencies.Fetchers {
|
||||||
tookSum += fetcherTimes[i]
|
tookSum += fetcherTimes[i]
|
||||||
times = times.Dur(fetcher.Name(), fetcherTimes[i])
|
times = times.Dur(fetcher.Name(), fetcherTimes[i])
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,11 +36,10 @@ func (cb *Base) getBase() *Base {
|
||||||
|
|
||||||
// Init initializes a new Ingredient.
|
// Init initializes a new Ingredient.
|
||||||
// Init is only intended to be used within a lifetime.Lifetime[Ingredient,*Liquid].
|
// Init is only intended to be used within a lifetime.Lifetime[Ingredient,*Liquid].
|
||||||
func Init(ingredient Ingredient, liquid *liquid.Liquid) Ingredient {
|
func Init(ingredient Ingredient, liquid *liquid.Liquid) {
|
||||||
base := ingredient.getBase() // pointer to a struct
|
base := ingredient.getBase() // pointer to a struct
|
||||||
base.Liquid = liquid
|
base.Liquid = liquid
|
||||||
base.name = strings.ToLower(reflect.TypeOf(ingredient).Elem().Name())
|
base.name = strings.ToLower(reflect.TypeOf(ingredient).Elem().Name())
|
||||||
return ingredient
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cb Base) Name() string {
|
func (cb Base) Name() string {
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ import (
|
||||||
// Prefixes implements reading and writing prefix
|
// Prefixes implements reading and writing prefix
|
||||||
type Adapters struct {
|
type Adapters struct {
|
||||||
ingredient.Base
|
ingredient.Base
|
||||||
Dependencies struct {
|
dependencies struct {
|
||||||
PHP *php.PHP
|
PHP *php.PHP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -33,7 +33,7 @@ type DistilleryAdapter struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wisski *Adapters) CreateDistilleryAdapter(ctx context.Context, server *phpx.Server, adapter DistilleryAdapter) error {
|
func (wisski *Adapters) CreateDistilleryAdapter(ctx context.Context, server *phpx.Server, adapter DistilleryAdapter) error {
|
||||||
return wisski.Dependencies.PHP.ExecScript(
|
return wisski.dependencies.PHP.ExecScript(
|
||||||
ctx, server, nil, adaptersPHP,
|
ctx, server, nil, adaptersPHP,
|
||||||
"create_distillery_adapter",
|
"create_distillery_adapter",
|
||||||
adapter.Label, adapter.MachineName, adapter.Description, adapter.InstanceDomain, adapter.GraphDBRepository, adapter.GraphDBUsername, adapter.GraphDBPassword,
|
adapter.Label, adapter.MachineName, adapter.Description, adapter.InstanceDomain, adapter.GraphDBRepository, adapter.GraphDBUsername, adapter.GraphDBPassword,
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ import (
|
||||||
|
|
||||||
type Blocks struct {
|
type Blocks struct {
|
||||||
ingredient.Base
|
ingredient.Base
|
||||||
Dependencies struct {
|
dependencies struct {
|
||||||
PHP *php.PHP
|
PHP *php.PHP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -31,11 +31,11 @@ type Block struct {
|
||||||
|
|
||||||
// Create creates a new block with the given title and html content
|
// Create creates a new block with the given title and html content
|
||||||
func (blocks *Blocks) Create(ctx context.Context, server *phpx.Server, block Block) (err error) {
|
func (blocks *Blocks) Create(ctx context.Context, server *phpx.Server, block Block) (err error) {
|
||||||
err = blocks.Dependencies.PHP.ExecScript(ctx, server, nil, blocksPHP, "create_basic_block", block.Info, block.Content, block.Region, block.BlockID)
|
err = blocks.dependencies.PHP.ExecScript(ctx, server, nil, blocksPHP, "create_basic_block", block.Info, block.Content, block.Region, block.BlockID)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (blocks *Blocks) GetFooterRegion(ctx context.Context, server *phpx.Server) (region string, err error) {
|
func (blocks *Blocks) GetFooterRegion(ctx context.Context, server *phpx.Server) (region string, err error) {
|
||||||
err = blocks.Dependencies.PHP.ExecScript(ctx, server, ®ion, blocksPHP, "get_footer_region")
|
err = blocks.dependencies.PHP.ExecScript(ctx, server, ®ion, blocksPHP, "get_footer_region")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ import (
|
||||||
|
|
||||||
type Pathbuilder struct {
|
type Pathbuilder struct {
|
||||||
ingredient.Base
|
ingredient.Base
|
||||||
Dependencies struct {
|
dependencies struct {
|
||||||
PHP *php.PHP
|
PHP *php.PHP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -29,7 +29,7 @@ var pathbuilderPHP string
|
||||||
//
|
//
|
||||||
// server is the server to fetch the pathbuilders from, any may be nil.
|
// server is the server to fetch the pathbuilders from, any may be nil.
|
||||||
func (pathbuilder *Pathbuilder) All(ctx context.Context, server *phpx.Server) (ids []string, err error) {
|
func (pathbuilder *Pathbuilder) All(ctx context.Context, server *phpx.Server) (ids []string, err error) {
|
||||||
err = pathbuilder.Dependencies.PHP.ExecScript(ctx, server, &ids, pathbuilderPHP, "all_list")
|
err = pathbuilder.dependencies.PHP.ExecScript(ctx, server, &ids, pathbuilderPHP, "all_list")
|
||||||
slices.Sort(ids)
|
slices.Sort(ids)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -39,7 +39,7 @@ func (pathbuilder *Pathbuilder) All(ctx context.Context, server *phpx.Server) (i
|
||||||
//
|
//
|
||||||
// server is the server to fetch the pathbuilders from, any may be nil.
|
// server is the server to fetch the pathbuilders from, any may be nil.
|
||||||
func (pathbuilder *Pathbuilder) Get(ctx context.Context, server *phpx.Server, id string) (xml string, err error) {
|
func (pathbuilder *Pathbuilder) Get(ctx context.Context, server *phpx.Server, id string) (xml string, err error) {
|
||||||
err = pathbuilder.Dependencies.PHP.ExecScript(ctx, server, &xml, pathbuilderPHP, "one_xml", id)
|
err = pathbuilder.dependencies.PHP.ExecScript(ctx, server, &xml, pathbuilderPHP, "one_xml", id)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -47,7 +47,7 @@ func (pathbuilder *Pathbuilder) Get(ctx context.Context, server *phpx.Server, id
|
||||||
//
|
//
|
||||||
// server is the server to fetch the pathbuilders from, any may be nil.
|
// server is the server to fetch the pathbuilders from, any may be nil.
|
||||||
func (pathbuilder *Pathbuilder) GetAll(ctx context.Context, server *phpx.Server) (pathbuilders map[string]string, err error) {
|
func (pathbuilder *Pathbuilder) GetAll(ctx context.Context, server *phpx.Server) (pathbuilders map[string]string, err error) {
|
||||||
err = pathbuilder.Dependencies.PHP.ExecScript(ctx, server, &pathbuilders, pathbuilderPHP, "all_xml")
|
err = pathbuilder.dependencies.PHP.ExecScript(ctx, server, &pathbuilders, pathbuilderPHP, "all_xml")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ import (
|
||||||
// Prefixes implements reading and writing prefix
|
// Prefixes implements reading and writing prefix
|
||||||
type Prefixes struct {
|
type Prefixes struct {
|
||||||
ingredient.Base
|
ingredient.Base
|
||||||
Dependencies struct {
|
dependencies struct {
|
||||||
PHP *php.PHP
|
PHP *php.PHP
|
||||||
MStore *mstore.MStore
|
MStore *mstore.MStore
|
||||||
}
|
}
|
||||||
|
|
@ -63,7 +63,7 @@ func (prefixes *Prefixes) All(ctx context.Context, server *phpx.Server) ([]strin
|
||||||
|
|
||||||
func (wisski *Prefixes) database(ctx context.Context, server *phpx.Server) (prefixes []string, err error) {
|
func (wisski *Prefixes) database(ctx context.Context, server *phpx.Server) (prefixes []string, err error) {
|
||||||
// get all the ugly prefixes
|
// get all the ugly prefixes
|
||||||
err = wisski.Dependencies.PHP.ExecScript(ctx, server, &prefixes, listURIPrefixesPHP, "list_prefixes")
|
err = wisski.dependencies.PHP.ExecScript(ctx, server, &prefixes, listURIPrefixesPHP, "list_prefixes")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -164,7 +164,7 @@ var prefix = mstore.For[string]("prefix")
|
||||||
|
|
||||||
// Prefixes returns the cached prefixes from the given instance
|
// Prefixes returns the cached prefixes from the given instance
|
||||||
func (wisski *Prefixes) AllCached(ctx context.Context) (results []string, err error) {
|
func (wisski *Prefixes) AllCached(ctx context.Context) (results []string, err error) {
|
||||||
return prefix.GetAll(ctx, wisski.Dependencies.MStore)
|
return prefix.GetAll(ctx, wisski.dependencies.MStore)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update updates the cached prefixes of this instance
|
// Update updates the cached prefixes of this instance
|
||||||
|
|
@ -173,7 +173,7 @@ func (wisski *Prefixes) Update(ctx context.Context) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return prefix.SetAll(ctx, wisski.Dependencies.MStore, prefixes...)
|
return prefix.SetAll(ctx, wisski.dependencies.MStore, prefixes...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (prefixes *Prefixes) Fetch(flags ingredient.FetcherFlags, info *status.WissKI) (err error) {
|
func (prefixes *Prefixes) Fetch(flags ingredient.FetcherFlags, info *status.WissKI) (err error) {
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package extras
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/phpx"
|
"github.com/FAU-CDI/wisski-distillery/internal/phpx"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/status"
|
"github.com/FAU-CDI/wisski-distillery/internal/status"
|
||||||
|
|
@ -14,7 +15,7 @@ import (
|
||||||
|
|
||||||
type Requirements struct {
|
type Requirements struct {
|
||||||
ingredient.Base
|
ingredient.Base
|
||||||
Dependencies struct {
|
dependencies struct {
|
||||||
PHP *php.PHP
|
PHP *php.PHP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -28,28 +29,28 @@ var requirementsPHP string
|
||||||
|
|
||||||
// Create creates a new block with the given title and html content
|
// Create creates a new block with the given title and html content
|
||||||
func (requirements *Requirements) Get(ctx context.Context, server *phpx.Server) (data []status.Requirement, err error) {
|
func (requirements *Requirements) Get(ctx context.Context, server *phpx.Server) (data []status.Requirement, err error) {
|
||||||
err = requirements.Dependencies.PHP.ExecScript(ctx, server, &data, requirementsPHP, "get_requirements", requirements.URL().String())
|
err = requirements.dependencies.PHP.ExecScript(ctx, server, &data, requirementsPHP, "get_requirements", requirements.URL().String())
|
||||||
if err == nil {
|
if err == nil {
|
||||||
// sort first by weight, then by id!
|
// sort first by weight, then by id!
|
||||||
slices.SortFunc(data, func(a, b status.Requirement) bool {
|
slices.SortFunc(data, func(a, b status.Requirement) int {
|
||||||
// compare first by weight
|
// compare first by weight
|
||||||
if a.Weight < b.Weight {
|
if a.Weight < b.Weight {
|
||||||
return true
|
return -1
|
||||||
}
|
}
|
||||||
if a.Weight > b.Weight {
|
if a.Weight > b.Weight {
|
||||||
return false
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
// then by severity
|
// then by severity
|
||||||
if a.Severity < b.Severity {
|
if a.Severity < b.Severity {
|
||||||
return true
|
return -1
|
||||||
}
|
}
|
||||||
if a.Severity > b.Severity {
|
if a.Severity > b.Severity {
|
||||||
return false
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
// and finally by id
|
// and finally by id
|
||||||
return a.ID < b.ID
|
return strings.Compare(a.ID, b.ID)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ import (
|
||||||
|
|
||||||
type Settings struct {
|
type Settings struct {
|
||||||
ingredient.Base
|
ingredient.Base
|
||||||
Dependencies struct {
|
dependencies struct {
|
||||||
PHP *php.PHP
|
PHP *php.PHP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -21,7 +21,7 @@ type Settings struct {
|
||||||
var settingsPHP string
|
var settingsPHP string
|
||||||
|
|
||||||
func (settings *Settings) Get(ctx context.Context, server *phpx.Server, key string) (value any, err error) {
|
func (settings *Settings) Get(ctx context.Context, server *phpx.Server, key string) (value any, err error) {
|
||||||
err = settings.Dependencies.PHP.ExecScript(ctx, server, &value, settingsPHP, "get_setting", key)
|
err = settings.dependencies.PHP.ExecScript(ctx, server, &value, settingsPHP, "get_setting", key)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -29,7 +29,7 @@ var errFailedToSetSetting = errors.New("failed to update setting")
|
||||||
|
|
||||||
func (settings *Settings) Set(ctx context.Context, server *phpx.Server, key string, value any) error {
|
func (settings *Settings) Set(ctx context.Context, server *phpx.Server, key string, value any) error {
|
||||||
var ok bool
|
var ok bool
|
||||||
err := settings.Dependencies.PHP.ExecScript(ctx, server, &ok, settingsPHP, "set_setting", key, value)
|
err := settings.dependencies.PHP.ExecScript(ctx, server, &ok, settingsPHP, "set_setting", key, value)
|
||||||
if err == nil && !ok {
|
if err == nil && !ok {
|
||||||
err = errFailedToSetSetting
|
err = errFailedToSetSetting
|
||||||
}
|
}
|
||||||
|
|
@ -41,7 +41,7 @@ var errFailedToSetTrustedDomain = errors.New("failed to set trusted domain")
|
||||||
func (settings *Settings) SetTrustedDomain(ctx context.Context, server *phpx.Server, domain string) error {
|
func (settings *Settings) SetTrustedDomain(ctx context.Context, server *phpx.Server, domain string) error {
|
||||||
var ok bool
|
var ok bool
|
||||||
|
|
||||||
err := settings.Dependencies.PHP.ExecScript(ctx, server, &ok, settingsPHP, "set_trusted_domain", domain)
|
err := settings.dependencies.PHP.ExecScript(ctx, server, &ok, settingsPHP, "set_trusted_domain", domain)
|
||||||
if err == nil && !ok {
|
if err == nil && !ok {
|
||||||
err = errFailedToSetTrustedDomain
|
err = errFailedToSetTrustedDomain
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ import (
|
||||||
|
|
||||||
type Stats struct {
|
type Stats struct {
|
||||||
ingredient.Base
|
ingredient.Base
|
||||||
Dependencies struct {
|
dependencies struct {
|
||||||
PHP *php.PHP
|
PHP *php.PHP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -26,7 +26,7 @@ var statsPHP string
|
||||||
|
|
||||||
// Get fetches all statistics from the server
|
// Get fetches all statistics from the server
|
||||||
func (stats *Stats) Get(ctx context.Context, server *phpx.Server) (data status.Statistics, err error) {
|
func (stats *Stats) Get(ctx context.Context, server *phpx.Server) (data status.Statistics, err error) {
|
||||||
err = stats.Dependencies.PHP.ExecScript(ctx, server, &data, statsPHP, "export_statistics")
|
err = stats.dependencies.PHP.ExecScript(ctx, server, &data, statsPHP, "export_statistics")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ import (
|
||||||
// Prefixes implements reading and writing prefix
|
// Prefixes implements reading and writing prefix
|
||||||
type Theme struct {
|
type Theme struct {
|
||||||
ingredient.Base
|
ingredient.Base
|
||||||
Dependencies struct {
|
dependencies struct {
|
||||||
PHP *php.PHP
|
PHP *php.PHP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -24,7 +24,7 @@ var themePHP string
|
||||||
|
|
||||||
// Get returns the currently active theme
|
// Get returns the currently active theme
|
||||||
func (t *Theme) Get(ctx context.Context, server *phpx.Server) (theme string, err error) {
|
func (t *Theme) Get(ctx context.Context, server *phpx.Server) (theme string, err error) {
|
||||||
err = t.Dependencies.PHP.ExecScript(
|
err = t.dependencies.PHP.ExecScript(
|
||||||
ctx, server, &theme, themePHP,
|
ctx, server, &theme, themePHP,
|
||||||
"get_active_theme",
|
"get_active_theme",
|
||||||
)
|
)
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue