Require access to Still via method

This commit adds a safeguard to accessing the still from a specific
component by requiring access via the component.GetStill method.
This commit is contained in:
Tom Wiesing 2024-04-08 22:39:32 +02:00
parent 81fa84c244
commit 8235ea9105
No known key found for this signature in database
63 changed files with 288 additions and 197 deletions

View file

@ -20,7 +20,8 @@ var errBlindUpdateFailed = exit.Error{
// Update performs a blind drush update
func (composer *Composer) Update(ctx context.Context, progress io.Writer) (err error) {
defer errBlindUpdateFailed.WithMessageF(composer.Slug).DeferWrap(&err)
defer errBlindUpdateFailed.WithMessageF(ingredient.GetLiquid(composer).Slug).DeferWrap(&err)
if err := composer.FixPermission(ctx, progress); err != nil {
return err

View file

@ -24,7 +24,7 @@ func (drush *Drush) Cron(ctx context.Context, progress io.Writer) error {
if err != nil {
code := err.(barrel.ExitError).Code
// keep going, because we want to run as many crons as possible
fmt.Fprintf(progress, "%v", errCronFailed.WithMessageF(drush.Slug, code))
fmt.Fprintf(progress, "%v", errCronFailed.WithMessageF(ingredient.GetLiquid(drush).Slug, code))
}
return nil

View file

@ -8,6 +8,7 @@ import (
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
"github.com/FAU-CDI/wisski-distillery/internal/models"
"github.com/FAU-CDI/wisski-distillery/internal/wisski/ingredient"
"github.com/FAU-CDI/wisski-distillery/internal/wisski/ingredient/barrel"
"github.com/FAU-CDI/wisski-distillery/internal/wisski/ingredient/barrel/composer"
"github.com/FAU-CDI/wisski-distillery/internal/wisski/ingredient/php/extras"
@ -106,7 +107,9 @@ func (provision *Manager) bootstrap(ctx context.Context, progress io.Writer, fla
}
}
var sqlDBURL = "mysql://" + provision.SqlUsername + ":" + provision.SqlPassword + "@sql/" + provision.SqlDatabase
liquid := ingredient.GetLiquid(provision)
var sqlDBURL = "mysql://" + liquid.SqlUsername + ":" + liquid.SqlPassword + "@sql/" + liquid.SqlDatabase
// Use 'drush' to run the site-installation.
// Here we need to use the username, password and database creds we made above.
@ -115,8 +118,8 @@ func (provision *Manager) bootstrap(ctx context.Context, progress io.Writer, fla
if err := provision.dependencies.Drush.Exec(
ctx, progress,
"site-install",
"standard", "--yes", "--site-name="+provision.Domain(),
"--account-name="+provision.DrupalUsername, "--account-pass="+provision.DrupalPassword,
"standard", "--yes", "--site-name="+liquid.Domain(),
"--account-name="+liquid.DrupalUsername, "--account-pass="+liquid.DrupalPassword,
"--db-url="+sqlDBURL,
); err != nil {
return err
@ -166,11 +169,11 @@ func (provision *Manager) bootstrap(ctx context.Context, progress io.Writer, fla
if err := provision.dependencies.Adapters.CreateDistilleryAdapter(ctx, nil, extras.DistilleryAdapter{
Label: "Default WissKI Distillery Adapter",
MachineName: "default",
Description: "Default Adapter for " + provision.Domain(),
InstanceDomain: provision.Domain(),
GraphDBRepository: provision.GraphDBRepository,
GraphDBUsername: provision.GraphDBUsername,
GraphDBPassword: provision.GraphDBPassword,
Description: "Default Adapter for " + liquid.Domain(),
InstanceDomain: liquid.Domain(),
GraphDBRepository: liquid.GraphDBRepository,
GraphDBUsername: liquid.GraphDBUsername,
GraphDBPassword: liquid.GraphDBPassword,
}); err != nil {
return err
}
@ -185,9 +188,9 @@ func (provision *Manager) bootstrap(ctx context.Context, progress io.Writer, fla
logging.LogMessage(progress, "Provisioning is now complete")
{
fmt.Fprintf(progress, "URL: %s\n", provision.URL())
fmt.Fprintf(progress, "Username: %s\n", provision.DrupalUsername)
fmt.Fprintf(progress, "Password: %s\n", provision.DrupalPassword)
fmt.Fprintf(progress, "URL: %s\n", liquid.URL())
fmt.Fprintf(progress, "Username: %s\n", liquid.DrupalUsername)
fmt.Fprintf(progress, "Password: %s\n", liquid.DrupalPassword)
}
return nil

View file

@ -10,7 +10,7 @@ import (
// Running checks if this WissKI is currently running.
func (barrel *Barrel) Running(ctx context.Context) (bool, error) {
containers, err := barrel.Docker.Containers(ctx, barrel.Stack().Dir)
containers, err := ingredient.GetLiquid(barrel).Docker.Containers(ctx, barrel.Stack().Dir)
if err != nil {
// The compose file is gone => the stack doesn't exist.
// Probably means some purging got interrupted.

View file

@ -18,7 +18,8 @@ var (
)
func (ssh *SSH) Keys(ctx context.Context) (keys []ssh.PublicKey, err error) {
grants, err := ssh.Liquid.Policy.Instance(ctx, ssh.Slug)
liquid := ingredient.GetLiquid(ssh)
grants, err := liquid.Policy.Instance(ctx, liquid.Slug)
if err != nil {
return nil, err
}
@ -28,7 +29,7 @@ func (ssh *SSH) Keys(ctx context.Context) (keys []ssh.PublicKey, err error) {
if !grant.DrupalAdminRole {
continue
}
ukeys, err := ssh.Liquid.Keys.Keys(ctx, grant.User)
ukeys, err := liquid.Keys.Keys(ctx, grant.User)
if err != nil {
return nil, err
}
@ -50,7 +51,7 @@ func (ssh *SSH) AllKeys(ctx context.Context) (keys []ssh.PublicKey, err error) {
return nil, err
}
gkeys, err := ssh.Liquid.Keys.Admin(ctx)
gkeys, err := ingredient.GetLiquid(ssh).Keys.Admin(ctx)
if err != nil {
return nil, err
}

View file

@ -5,6 +5,7 @@ import (
"path/filepath"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
"github.com/FAU-CDI/wisski-distillery/internal/wisski/ingredient"
)
//go:embed all:barrel
@ -17,9 +18,12 @@ var localSettingsTemplate string
// Barrel returns a stack representing the running WissKI Instance
func (barrel *Barrel) Stack() component.StackWithResources {
liquid := ingredient.GetLiquid(barrel)
config := ingredient.GetStill(barrel).Config
return component.StackWithResources{
Stack: component.Stack{
Dir: barrel.FilesystemBase,
Dir: liquid.FilesystemBase,
},
Resources: barrelResources,
@ -30,23 +34,23 @@ func (barrel *Barrel) Stack() component.StackWithResources {
},
EnvContext: map[string]string{
"DOCKER_NETWORK_NAME": barrel.Malt.Config.Docker.Network(),
"DOCKER_NETWORK_NAME": config.Docker.Network(),
"SLUG": barrel.Slug,
"HOST_RULE": barrel.HostRule(),
"WISSKI_HOSTNAME": barrel.Hostname(),
"HTTPS_ENABLED": barrel.Malt.Config.HTTP.HTTPSEnabledEnv(),
"SLUG": liquid.Slug,
"HOST_RULE": liquid.HostRule(),
"WISSKI_HOSTNAME": liquid.Hostname(),
"HTTPS_ENABLED": config.HTTP.HTTPSEnabledEnv(),
"DATA_PATH": filepath.Join(barrel.FilesystemBase, "data"),
"RUNTIME_DIR": barrel.Malt.Config.Paths.RuntimeDir(),
"DATA_PATH": filepath.Join(liquid.FilesystemBase, "data"),
"RUNTIME_DIR": config.Paths.RuntimeDir(),
"LOCAL_SETTINGS_PATH": filepath.Join(barrel.FilesystemBase, localSettingsName),
"LOCAL_SETTINGS_PATH": filepath.Join(liquid.FilesystemBase, localSettingsName),
"LOCAL_SETTINGS_MOUNT": LocalSettingsPath,
"BARREL_BASE_IMAGE": barrel.GetDockerBaseImage(),
"IIP_SERVER_ENABLED": barrel.GetIIPServerEnabled(),
"OPCACHE_MODE": barrel.OpCacheMode(),
"CONTENT_SECURITY_POLICY": barrel.ContentSecurityPolicy,
"BARREL_BASE_IMAGE": liquid.GetDockerBaseImage(),
"IIP_SERVER_ENABLED": liquid.GetIIPServerEnabled(),
"OPCACHE_MODE": liquid.OpCacheMode(),
"CONTENT_SECURITY_POLICY": liquid.ContentSecurityPolicy,
},
MakeDirs: []string{"data", ".composer"},

View file

@ -4,6 +4,7 @@ import (
"context"
"io"
"github.com/FAU-CDI/wisski-distillery/internal/wisski/ingredient"
"github.com/FAU-CDI/wisski-distillery/pkg/logging"
)
@ -12,7 +13,7 @@ import (
func (smanager *SystemManager) BuildSettings(ctx context.Context, progress io.Writer) (err error) {
logging.LogMessage(progress, "Updating TRUSTED_HOST_PATTERNS in settings.php")
{
if err := smanager.dependencies.Settings.SetTrustedDomain(ctx, nil, smanager.Domain()); err != nil {
if err := smanager.dependencies.Settings.SetTrustedDomain(ctx, nil, ingredient.GetLiquid(smanager).Domain()); err != nil {
return err
}
}

View file

@ -43,7 +43,7 @@ func (smanager *SystemManager) ApplyInitial(ctx context.Context, progress io.Wri
// start inidicates if the image should be started afterwards
func (smanager *SystemManager) apply(ctx context.Context, progress io.Writer, system models.System, start bool) error {
// store the new system configuration
smanager.Instance.System = system
ingredient.GetLiquid(smanager).Instance.System = system
if err := smanager.dependencies.Bookkeeping.Save(ctx); err != nil {
return err
}

View file

@ -13,32 +13,34 @@ type Bookkeeping struct {
// Save saves this instance in the bookkeeping table
func (bk *Bookkeeping) Save(ctx context.Context) error {
sdb, err := bk.Malt.SQL.QueryTable(ctx, bk.Malt.InstanceTable)
liquid := ingredient.GetLiquid(bk)
sdb, err := ingredient.GetLiquid(bk).Malt.SQL.QueryTable(ctx, liquid.Malt.InstanceTable)
if err != nil {
return err
}
// it has never been created => we need to create it in the database
if bk.Instance.Created.IsZero() {
return sdb.Create(&bk.Instance).Error
if liquid.Instance.Created.IsZero() {
return sdb.Create(&liquid.Instance).Error
}
// Update based on the primary key!
return sdb.Select("*").Save(&bk.Instance).Error
return sdb.Select("*").Save(&liquid.Instance).Error
}
// Delete deletes this instance from the bookkeeping table
func (bk *Bookkeeping) Delete(ctx context.Context) error {
sdb, err := bk.Malt.SQL.QueryTable(ctx, bk.Malt.InstanceTable)
liquid := ingredient.GetLiquid(bk)
sdb, err := liquid.SQL.QueryTable(ctx, liquid.InstanceTable)
if err != nil {
return err
}
// doesn't exist => nothing to delete
if bk.Instance.Created.IsZero() {
if liquid.Instance.Created.IsZero() {
return nil
}
// delete it directly
return sdb.Delete(&bk.Instance).Error
return sdb.Delete(&liquid.Instance).Error
}

View file

@ -29,7 +29,7 @@ var (
)
// Information fetches information about this WissKI.
func (wisski *Info) Information(ctx context.Context, quick bool) (info status.WissKI, err error) {
func (nfo *Info) Information(ctx context.Context, quick bool) (info status.WissKI, err error) {
// setup flags
flags := ingredient.FetcherFlags{
Quick: quick,
@ -43,7 +43,7 @@ func (wisski *Info) Information(ctx context.Context, quick bool) (info status.Wi
Limit: 5,
New: func() *phpx.Server {
atomic.AddUint64(&serversUsed, 1)
return wisski.dependencies.PHP.NewServer()
return nfo.dependencies.PHP.NewServer()
},
Discard: func(s *phpx.Server) {
s.Close()
@ -53,7 +53,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.
// 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(nfo.dependencies.Fetchers))
recordTime := func(i int) func() {
start := time.Now()
return func() {
@ -64,7 +64,7 @@ func (wisski *Info) Information(ctx context.Context, quick bool) (info status.Wi
start := time.Now()
{
var group errgroup.Group
for i, fetcher := range wisski.dependencies.Fetchers {
for i, fetcher := range nfo.dependencies.Fetchers {
fetcher, flags, i := fetcher, flags, i
group.Go(func() error {
// quick: don't need to create servers
@ -101,7 +101,7 @@ func (wisski *Info) Information(ctx context.Context, quick bool) (info status.Wi
// get a map of how long each fetcher took
times := zerolog.Dict()
for i, fetcher := range wisski.dependencies.Fetchers {
for i, fetcher := range nfo.dependencies.Fetchers {
tookSum += fetcherTimes[i]
times = times.Dur(fetcher.Name(), fetcherTimes[i])
}
@ -115,9 +115,11 @@ func (wisski *Info) Information(ctx context.Context, quick bool) (info status.Wi
return
}
func (wisski *Info) Fetch(flags ingredient.FetcherFlags, info *status.WissKI) error {
func (nfo *Info) Fetch(flags ingredient.FetcherFlags, info *status.WissKI) error {
liquid := ingredient.GetLiquid(nfo)
info.Time = time.Now().UTC()
info.Slug = wisski.Slug
info.URL = wisski.URL().String()
info.Slug = liquid.Slug
info.URL = liquid.URL().String()
return nil
}

View file

@ -18,6 +18,6 @@ func (lbr *SnapshotsFetcher) Fetch(flags ingredient.FetcherFlags, info *status.W
return
}
info.Snapshots, _ = lbr.Snapshots(flags.Context)
info.Snapshots, _ = ingredient.GetLiquid(lbr).Snapshots(flags.Context)
return
}

View file

@ -4,6 +4,7 @@ import (
"reflect"
"strings"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
"github.com/FAU-CDI/wisski-distillery/internal/wisski/liquid"
)
@ -25,8 +26,18 @@ type Ingredient interface {
// Base is embedded into every Ingredient
type Base struct {
name string // name is the name of this ingredient
*liquid.Liquid // the underlying liquid
name string // name is the name of this ingredient
liquid *liquid.Liquid // the underlying liquid
}
// GetLiquid gets the liquid of this Ingredient
func GetLiquid(i Ingredient) *liquid.Liquid {
return i.getBase().liquid
}
// GetStill returns the still of the distillery associated with the provided ingredient.
func GetStill(i Ingredient) component.Still {
return component.GetStill(GetLiquid(i).Malt)
}
//lint:ignore U1000 used to implement the private methods of [Component]
@ -38,7 +49,7 @@ func (cb *Base) getBase() *Base {
// Init is only intended to be used within a lifetime.Lifetime[Ingredient,*Liquid].
func Init(ingredient Ingredient, liquid *liquid.Liquid) {
base := ingredient.getBase() // pointer to a struct
base.Liquid = liquid
base.liquid = liquid
base.name = strings.ToLower(reflect.TypeOf(ingredient).Elem().Name())
}

View file

@ -26,26 +26,30 @@ var Locked = exit.Error{
// TryLock attemps to lock this WissKI and returns if it suceeded
func (lock *Locker) TryLock(ctx context.Context) bool {
table, err := lock.Malt.SQL.QueryTable(ctx, lock.Malt.LockTable)
liquid := ingredient.GetLiquid(lock)
table, err := liquid.SQL.QueryTable(ctx, liquid.LockTable)
if err != nil {
return false
}
result := table.FirstOrCreate(&models.Lock{}, models.Lock{Slug: lock.Slug})
result := table.FirstOrCreate(&models.Lock{}, models.Lock{Slug: liquid.Slug})
return result.Error == nil && result.RowsAffected == 1
}
// TryUnlock attempts to unlock this WissKI and reports if it succeeded.
// An Unlock is also attempted when ctx is cancelled.
func (lock *Locker) TryUnlock(ctx context.Context) bool {
liquid := ingredient.GetLiquid(lock)
ctx, close := contextx.Anyways(ctx, time.Second)
defer close()
table, err := lock.Malt.SQL.QueryTable(ctx, lock.Malt.LockTable)
table, err := liquid.SQL.QueryTable(ctx, liquid.LockTable)
if err != nil {
return false
}
result := table.Where("slug = ?", lock.Slug).Delete(&models.Lock{})
result := table.Where("slug = ?", liquid.Slug).Delete(&models.Lock{})
return result.Error == nil && result.RowsAffected == 1
}

View file

@ -10,13 +10,15 @@ import (
// Locked checks if this WissKI is currently locked.
// If an error occurs, the instance is considered not locked.
func (lock *Locker) Locked(ctx context.Context) (locked bool) {
table, err := lock.Malt.SQL.QueryTable(ctx, lock.Malt.LockTable)
liquid := ingredient.GetLiquid(lock)
table, err := liquid.SQL.QueryTable(ctx, liquid.LockTable)
if err != nil {
return false
}
// check if this instance is locked
table.Select("count(*) > 0").Where("slug = ?", lock.Slug).Find(&locked)
table.Select("count(*) > 0").Where("slug = ?", liquid.Slug).Find(&locked)
return
}

View file

@ -35,8 +35,10 @@ var (
// NoPrefix checks if this WissKI instance is excluded from generating prefixes.
// TODO: Move this to the database!
func (prefixes *Prefixes) NoPrefix() bool {
liquid := ingredient.GetLiquid(prefixes)
// FIXME: Ignoring error here!
exists, _ := fsx.IsRegular(filepath.Join(prefixes.FilesystemBase, "prefixes.skip"), false)
exists, _ := fsx.IsRegular(filepath.Join(liquid.FilesystemBase, "prefixes.skip"), false)
return exists
}
@ -63,9 +65,8 @@ func (prefixes *Prefixes) All(ctx context.Context, server *phpx.Server) ([]strin
// getLivePrefixes get the list of prefixes found within the live system
func (prefixes *Prefixes) getLivePrefixes(ctx context.Context, server *phpx.Server) (pfs []string, err error) {
useTS := !(prefixes.Config.TS.DangerouslyUseAdapterPrefixes.Set && prefixes.Config.TS.DangerouslyUseAdapterPrefixes.Value)
if useTS {
danger := ingredient.GetStill(prefixes).Config.TS.DangerouslyUseAdapterPrefixes
if !(danger.Set && danger.Value) {
pfs, err = prefixes.getTSPrefixes(ctx, server)
} else {
// danger danger danger: Use the adapter prefixes
@ -107,9 +108,11 @@ func (wisski *Prefixes) getTSPrefixes(ctx context.Context, server *phpx.Server)
}
func (prefixes *Prefixes) blocked() ([]string, error) {
config := ingredient.GetStill(prefixes).Config
// open the resolver block file
// TODO: move this to the distillery
file, err := os.Open(prefixes.Malt.Config.Paths.ResolverBlocks)
file, err := os.Open(config.Paths.ResolverBlocks)
if err != nil {
return nil, err
}
@ -145,7 +148,7 @@ func hasAnyPrefix(candidate string, prefixes []string) bool {
}
func (wisski *Prefixes) filePrefixes() (prefixes []string, err error) {
path := filepath.Join(wisski.FilesystemBase, "prefixes")
path := filepath.Join(ingredient.GetLiquid(wisski).FilesystemBase, "prefixes")
// check that the prefixes path exists
{

View file

@ -29,7 +29,7 @@ var requirementsPHP string
// 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) {
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", ingredient.GetLiquid(requirements).URL().String())
if err == nil {
// sort first by weight, then by id!
slices.SortFunc(data, func(a, b status.Requirement) int {

View file

@ -19,6 +19,7 @@ func (up *UserPolicy) Fetch(flags ingredient.FetcherFlags, target *status.WissKI
}
// read the grants into the info struct
target.Grants, err = up.Malt.Policy.Instance(flags.Context, up.Slug)
liquid := ingredient.GetLiquid(up)
target.Grants, err = liquid.Policy.Instance(flags.Context, liquid.Slug)
return err
}

View file

@ -71,7 +71,7 @@ func (u *Users) LoginWithOpt(ctx context.Context, server *phpx.Server, username
}
// and resolve the (possibly relative) reference
dest = u.URL().ResolveReference(dest)
dest = ingredient.GetLiquid(u).URL().ResolveReference(dest)
return
}

View file

@ -19,20 +19,22 @@ var reserveResources embed.FS
// Stack returns a stack representing the reserve instance
func (reserve *Reserve) Stack() component.StackWithResources {
liquid := ingredient.GetLiquid(reserve)
config := ingredient.GetStill(reserve).Config
return component.StackWithResources{
Stack: component.Stack{
Dir: reserve.FilesystemBase,
Dir: liquid.FilesystemBase,
},
Resources: reserveResources,
ContextPath: filepath.Join("reserve"),
EnvContext: map[string]string{
"DOCKER_NETWORK_NAME": reserve.Malt.Config.Docker.Network(),
"DOCKER_NETWORK_NAME": config.Docker.Network(),
"SLUG": reserve.Slug,
"HOST_RULE": reserve.HostRule(),
"HTTPS_ENABLED": reserve.Malt.Config.HTTP.HTTPSEnabledEnv(),
"SLUG": liquid.Slug,
"HOST_RULE": liquid.HostRule(),
"HTTPS_ENABLED": config.HTTP.HTTPSEnabledEnv(),
},
}
}

View file

@ -46,13 +46,15 @@ func (trb *TRB) RebuildTriplestore(ctx context.Context, out io.Writer, allowEmpt
}
fmt.Printf("Wrote %q\n", dumpPath)
liquid := ingredient.GetLiquid(trb)
logging.LogMessage(out, "Purging triplestore")
if err := trb.Malt.TS.Purge(ctx, trb.Instance, trb.Domain()); err != nil {
if err := liquid.TS.Purge(ctx, liquid.Instance, liquid.Domain()); err != nil {
return err
}
logging.LogMessage(out, "Provising triplestore")
if err := trb.Malt.TS.Provision(ctx, trb.Instance, trb.Domain()); err != nil {
if err := liquid.TS.Provision(ctx, liquid.Instance, liquid.Domain()); err != nil {
return err
}
@ -82,7 +84,9 @@ func (trb *TRB) makeBackup(ctx context.Context, allowEmptyRepository bool) (path
zippedFile := gzip.NewWriter(file)
defer zippedFile.Close()
count, err := trb.Malt.TS.SnapshotDB(ctx, zippedFile, trb.GraphDBRepository)
liquid := ingredient.GetLiquid(trb)
count, err := liquid.TS.SnapshotDB(ctx, zippedFile, liquid.GraphDBRepository)
if err != nil {
return "", err
}
@ -107,7 +111,8 @@ func (trb *TRB) restoreBackup(ctx context.Context, path string) (err error) {
}
defer decompressedReader.Close()
if err := trb.Malt.TS.RestoreDB(ctx, trb.GraphDBRepository, decompressedReader); err != nil {
liquid := ingredient.GetLiquid(trb)
if err := liquid.TS.RestoreDB(ctx, liquid.GraphDBRepository, decompressedReader); err != nil {
return err
}
return nil

View file

@ -4,11 +4,12 @@ import (
"net/url"
"github.com/FAU-CDI/wisski-distillery/internal/config"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
)
// Domain returns the full domain name of this WissKI
func (liquid *Liquid) Domain() string {
return liquid.Config.HTTP.HostFromSlug(liquid.Slug)
return component.GetStill(liquid).Config.HTTP.HostFromSlug(liquid.Slug)
}
func (liquid *Liquid) Hostname() string {
@ -29,7 +30,7 @@ func (liquid *Liquid) URL() *url.URL {
}
// use http or https scheme depending on if the distillery has it enabled
if liquid.Malt.Config.HTTP.HTTPSEnabled() {
if component.GetStill(liquid.Malt).Config.HTTP.HTTPSEnabled() {
url.Scheme = "https"
} else {
url.Scheme = "http"

View file

@ -9,7 +9,7 @@ import (
// Liquid is the core of a WissKI Instance and used in every ingredient.
type Liquid struct {
*malt.Malt
models.Instance
models.Instance // TODO: move this into an explicit field
DrupalUsername string
DrupalPassword string