home: allow disableing list
This commit is contained in:
parent
35544bd64c
commit
5e9795ad0c
9 changed files with 127 additions and 32 deletions
|
|
@ -24,7 +24,7 @@ type Config struct {
|
||||||
Listen ListenConfig `yaml:"listen" recurse:"true"`
|
Listen ListenConfig `yaml:"listen" recurse:"true"`
|
||||||
Paths PathsConfig `yaml:"paths" recurse:"true"`
|
Paths PathsConfig `yaml:"paths" recurse:"true"`
|
||||||
HTTP HTTPConfig `yaml:"http" recurse:"true"`
|
HTTP HTTPConfig `yaml:"http" recurse:"true"`
|
||||||
Theme ThemeConfig `yaml:"theme" recurse:"true"`
|
Home HomeConfig `yaml:"home" recurse:"true"`
|
||||||
Docker DockerConfig `yaml:"docker" recurse:"true"`
|
Docker DockerConfig `yaml:"docker" recurse:"true"`
|
||||||
|
|
||||||
SQL SQLConfig `yaml:"sql" recurse:"true"`
|
SQL SQLConfig `yaml:"sql" recurse:"true"`
|
||||||
|
|
|
||||||
|
|
@ -39,10 +39,24 @@ http:
|
||||||
# This email address can be configured here.
|
# This email address can be configured here.
|
||||||
certbot_email: null
|
certbot_email: null
|
||||||
|
|
||||||
# By default, the default domain redirects to the distillery repository.
|
# Configuration for the (public) homepage of the distillery.
|
||||||
# If you want to change this, set an alternate domain name here.
|
home:
|
||||||
theme:
|
# the url to redirect to for more information about this instance of the distillery.
|
||||||
home: null
|
# to be configured by default.
|
||||||
|
redirect: null
|
||||||
|
|
||||||
|
# configure the list of systems on the homepage.
|
||||||
|
list:
|
||||||
|
# is the list of WissKIs visible for the public?
|
||||||
|
# if this is disabled, only the generic text is shown.
|
||||||
|
public: null
|
||||||
|
|
||||||
|
# is the list of WissKIs visible to logged in users?
|
||||||
|
# if this is disabled, only the generic text is shown.
|
||||||
|
private: null
|
||||||
|
|
||||||
|
# Title of the list (whenever it is shown)
|
||||||
|
title: null
|
||||||
|
|
||||||
docker:
|
docker:
|
||||||
# The distillery uses several global docker networks.
|
# The distillery uses several global docker networks.
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,17 @@ package config
|
||||||
|
|
||||||
import "github.com/FAU-CDI/wisski-distillery/internal/config/validators"
|
import "github.com/FAU-CDI/wisski-distillery/internal/config/validators"
|
||||||
|
|
||||||
// ThemeConfig determines theming options
|
// HomeConfig determines options for the homepage of the distillery
|
||||||
type ThemeConfig struct {
|
type HomeConfig struct {
|
||||||
// By default, the default domain redirects to the distillery repository.
|
SelfRedirect *validators.URL `yaml:"redirect" default:"https://github.com/FAU-CDI/wisski-distillery" validate:"https"`
|
||||||
// If you want to change this, set an alternate domain name here.
|
List HomeListConfig `yaml:"list" recurse:"true"`
|
||||||
SelfRedirect *validators.URL `yaml:"home" default:"https://github.com/FAU-CDI/wisski-distillery" validate:"https"`
|
}
|
||||||
|
|
||||||
|
type HomeListConfig struct {
|
||||||
|
// Is the list enabled for public visits?
|
||||||
|
Public validators.NullableBool `yaml:"public" default:"true" validate:"bool"`
|
||||||
|
// Is the list enabled for signed-in visits?
|
||||||
|
Private validators.NullableBool `yaml:"private" default:"true" validate:"bool"`
|
||||||
|
// Title of the list whenever it is shown
|
||||||
|
Title string `yaml:"title" default:"WissKIs on this Distillery" validate:"nonempty"`
|
||||||
}
|
}
|
||||||
|
|
|
||||||
41
internal/config/validators/bool.go
Normal file
41
internal/config/validators/bool.go
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
package validators
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NullableBool represents a bool that can be null
|
||||||
|
type NullableBool struct {
|
||||||
|
Null, Value bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (nb *NullableBool) UnmarshalYAML(value *yaml.Node) error {
|
||||||
|
nb.Null = false
|
||||||
|
if err := value.Decode(&nb.Value); err != nil {
|
||||||
|
nb.Null = true
|
||||||
|
nb.Value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (nb *NullableBool) MarshalYAML() (interface{}, error) {
|
||||||
|
if nb.Null {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
return nb.Value, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ValidateBool(value *NullableBool, dflt string) (err error) {
|
||||||
|
if value.Null {
|
||||||
|
res, err := strconv.ParseBool(dflt)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
value.Null = false
|
||||||
|
value.Value = res
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
@ -10,6 +10,8 @@ func New() validator.Collection {
|
||||||
|
|
||||||
validator.Add(coll, "nonempty", ValidateNonempty)
|
validator.Add(coll, "nonempty", ValidateNonempty)
|
||||||
|
|
||||||
|
validator.Add(coll, "bool", ValidateBool)
|
||||||
|
|
||||||
validator.Add(coll, "directory", ValidateDirectory)
|
validator.Add(coll, "directory", ValidateDirectory)
|
||||||
validator.Add(coll, "file", ValidateFile)
|
validator.Add(coll, "file", ValidateFile)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
||||||
|
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/auth"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/instances"
|
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/instances"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/templating"
|
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/templating"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/status"
|
"github.com/FAU-CDI/wisski-distillery/internal/status"
|
||||||
|
|
@ -17,6 +18,7 @@ type Home struct {
|
||||||
Dependencies struct {
|
Dependencies struct {
|
||||||
Templating *templating.Templating
|
Templating *templating.Templating
|
||||||
Instances *instances.Instances
|
Instances *instances.Instances
|
||||||
|
Auth *auth.Auth
|
||||||
}
|
}
|
||||||
|
|
||||||
instanceNames lazy.Lazy[map[string]struct{}] // instance names
|
instanceNames lazy.Lazy[map[string]struct{}] // instance names
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,8 @@ var aboutTemplate = template.Must(template.New("about.html").Parse(aboutHTML))
|
||||||
|
|
||||||
// aboutContext is passed to about.html
|
// aboutContext is passed to about.html
|
||||||
type aboutContext struct {
|
type aboutContext struct {
|
||||||
Instances []status.WissKI
|
Instances []status.WissKI // list of WissKI Instancaes
|
||||||
|
SignedIn bool // is there a signed in user?
|
||||||
Logo template.HTML
|
Logo template.HTML
|
||||||
SelfRedirect string
|
SelfRedirect string
|
||||||
}
|
}
|
||||||
|
|
@ -38,6 +39,10 @@ type publicContext struct {
|
||||||
templating.RuntimeFlags
|
templating.RuntimeFlags
|
||||||
|
|
||||||
aboutContext
|
aboutContext
|
||||||
|
|
||||||
|
ListEnabled bool // is the list of instances enabled?
|
||||||
|
ListTitle string // what is the title of the list of instances?
|
||||||
|
|
||||||
About template.HTML
|
About template.HTML
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -66,7 +71,11 @@ 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.homeInstances.Get(nil)
|
pc.aboutContext.Instances = home.homeInstances.Get(nil)
|
||||||
pc.aboutContext.SelfRedirect = home.Config.Theme.SelfRedirect.String()
|
pc.aboutContext.SelfRedirect = home.Config.Home.SelfRedirect.String()
|
||||||
|
{
|
||||||
|
user, _ := home.Dependencies.Auth.UserOf(r)
|
||||||
|
pc.aboutContext.SignedIn = user != nil
|
||||||
|
}
|
||||||
|
|
||||||
// render the about template
|
// render the about template
|
||||||
|
|
||||||
|
|
@ -77,6 +86,17 @@ func (home *Home) publicHandler(ctx context.Context) http.Handler {
|
||||||
// and return about!
|
// and return about!
|
||||||
pc.About = template.HTML(builder.String())
|
pc.About = template.HTML(builder.String())
|
||||||
|
|
||||||
|
// user is not signed in!
|
||||||
|
|
||||||
|
if pc.aboutContext.SignedIn {
|
||||||
|
pc.ListEnabled = home.Config.Home.List.Private.Value
|
||||||
|
} else {
|
||||||
|
pc.ListEnabled = home.Config.Home.List.Public.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
// title of the list
|
||||||
|
pc.ListTitle = home.Config.Home.List.Title
|
||||||
|
|
||||||
return
|
return
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,25 +1,27 @@
|
||||||
{{ .About }}
|
{{ .About }}
|
||||||
|
|
||||||
<div class="pure-u-1">
|
{{ if .ListEnabled }}
|
||||||
<h2>WissKIs on this Distillery</h2>
|
<div class="pure-u-1">
|
||||||
</div>
|
<h2>{{ .ListTitle }}</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
{{range .Instances}}
|
{{range .Instances}}
|
||||||
{{ if and .Running (not .NoPrefixes) }}
|
{{ if and .Running (not .NoPrefixes) }}
|
||||||
<div class="pure-u-1 pure-u-md-1-3">
|
<div class="pure-u-1 pure-u-md-1-3">
|
||||||
<h3>{{.Slug}}</h3>
|
<h3>{{.Slug}}</h3>
|
||||||
<p>
|
<p>
|
||||||
<a href="{{.URL}}" target="_blank" rel="noopener noreferrer" class="wisskilink">{{.URL}}</a><br>
|
<a href="{{.URL}}" target="_blank" rel="noopener noreferrer" class="wisskilink">{{.URL}}</a><br>
|
||||||
<small>
|
<small>
|
||||||
{{ .Statistics.Bundles.Summary }}
|
{{ .Statistics.Bundles.Summary }}
|
||||||
|
|
||||||
{{ $edit := .Statistics.Bundles.LastEdit }}
|
{{ $edit := .Statistics.Bundles.LastEdit }}
|
||||||
{{ if $edit.Valid }}
|
{{ if $edit.Valid }}
|
||||||
<br />
|
<br />
|
||||||
last edited {{ $edit.Time.Format "2006-01-02T15:04:05Z07:00" }}
|
last edited {{ $edit.Time.Format "2006-01-02T15:04:05Z07:00" }}
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</small>
|
</small>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
{{ end }}
|
||||||
{{ end }}
|
{{ end }}
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
@ -59,6 +59,12 @@ var errUserIsNotRoot = exit.Error{
|
||||||
Message: "this command has to be executed as root. the current user is not root",
|
Message: "this command has to be executed as root. the current user is not root",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// an error when cgo is enabled
|
||||||
|
var errCGoEnabled = exit.Error{
|
||||||
|
ExitCode: exit.ExitGeneralArguments,
|
||||||
|
Message: "this command has to be executed as root. the current user is not root",
|
||||||
|
}
|
||||||
|
|
||||||
const warnNoDeployWdcli = "Warning: Not using %q executable at %q. This might leave the distillery in an inconsistent state. \n"
|
const warnNoDeployWdcli = "Warning: Not using %q executable at %q. This might leave the distillery in an inconsistent state. \n"
|
||||||
|
|
||||||
func NewProgram() Program {
|
func NewProgram() Program {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue