Refactor server and templates package

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

View file

@ -0,0 +1,7 @@
---
title: Migration to go
date: 2022-09-08
---
- We have ported the distillery from a set of bash scripts to a self-contained go executable
- This makes future development easier, and allows us to develop new features easier

View file

@ -0,0 +1,10 @@
---
title: Addition of an administrative server
date: 2022-09-09
---
- We have added a new web route under `/dis/`
- Allows administrators to manage WissKI Instances and see their status
- Administrators can e.g. download pathbuilders and make backups and snapshots
- At this point it is only for administrators
- A future (public) server with statistics will follow

View file

@ -0,0 +1,8 @@
---
title: Addition of a Global Distillery Resolver
date: 2022-10-05
---
- We have added a global WissKI Resolver, that functions similarly to the WissKI resolver under `/wisski/`.
- It can resolve WissKI URIs for the entire distillery, and redirect to their view page.
- Can be called exactly like the `/wisski/get?uri=` route of individual WissKIs, but toplevel on the distillery.

View file

@ -0,0 +1,8 @@
---
title: Migration to Traefik & Support for HTTP3
date: 2022-10-12
---
- We have migrated the entry point from nginx to [traefik](https://traefik.io/traefik/)
- This enables much cleaner support for automatically fetching and renewing SSL certificates
- It is now possible to turn on http3 support for the entire distillery

View file

@ -0,0 +1,8 @@
---
title: Refactored SSH Support
date: 2022-11-12
---
- Fully refactored ssh for users to use a real OpenSSH Server along with a small custom proxy in between
- It is now possible for developers to directly use e.g. [VSCode Remote SSH](https://code.visualstudio.com/docs/remote/ssh) to develop new WissKI features directly on the distillery.
- No configuration beyond regular ssh access is neccessary

View file

@ -0,0 +1,7 @@
---
title: Showing Statistics
date: 2022-11-16
---
- The distillery nows shows generic statistics on the public homepage
- detailed statistics can be found on the admin interface

View file

@ -0,0 +1,6 @@
---
title: Login using Distillery Administration
date: 2022-11-23
---
- The admin interface now allows login to individual user accounts

View file

@ -0,0 +1,6 @@
---
title: Automatic Password Checking
date: 2022-11-25
---
- Implemented automatic password checking

View file

@ -0,0 +1,15 @@
---
title: User And Instance Management
date: 2023-01-07
---
- the concept of distillery user accounts has been added
- their accounts have a password as well as TOTP
- users can manage their own account details
- administrators can reset user passwords, and disable TOTP
- distillery accounts can be linked to multiple drupal accounts
- users can sign into the account without entering further passwords
- users must have two-factor-authentication enabled to use this functionality
- administrators have access to the distillery admin panel
- the functionality to manage distillery accounts has been added
- the functionality to link distillery and drupal accounts has been added

View file

@ -0,0 +1,6 @@
---
title: News on the homepage
date: 2023-01-09
---
- we are now linking and showing the news section from the homepage

View file

@ -0,0 +1,9 @@
---
title: Reworked SSH key support
date: 2023-01-15
---
- reworked and added ssh key management to the server
- users can now add and remove ssh keys to their account
- each user with an admin grant for a specific instance has ssh access via their keys
- distillery administrators have implicit access to all instances

View file

@ -0,0 +1,6 @@
---
title: Removing instances from admin interface
date: 2023-01-16
---
- added an option to purge and remove instances from the admin page

View file

@ -0,0 +1,140 @@
package news
import (
"context"
"embed"
"html/template"
"io/fs"
"net/http"
"strings"
"time"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/assets"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/templates"
"github.com/rs/zerolog"
"github.com/yuin/goldmark"
gmmeta "github.com/yuin/goldmark-meta"
"github.com/yuin/goldmark/parser"
"golang.org/x/exp/slices"
)
type News struct {
component.Base
Dependencies struct {
Templating *templates.Templating
}
}
var (
_ component.Routeable = (*News)(nil)
)
func (*News) Routes() component.Routes {
return component.Routes{
Prefix: "/news/",
Exact: true,
CSRF: false,
MenuTitle: "News",
MenuPriority: component.MenuNews,
}
}
type Item struct {
ID string
Date time.Time
Title string
Content template.HTML
}
func (item *Item) parse(path string, builder *strings.Builder) error {
builder.Reset()
// open file
content, err := fs.ReadFile(newsFS, path)
if err != nil {
return err
}
// parse and read metadata
reader := goldmark.New(goldmark.WithExtensions(
gmmeta.Meta,
))
context := parser.NewContext()
if err := reader.Convert(content, builder, parser.WithContext(context)); err != nil {
return err
}
meta := gmmeta.Get(context)
// read title
item.Title, _ = meta["title"].(string)
// read date
date, _ := meta["date"].(string)
item.Date, err = time.Parse("2006-01-02", date)
if err != nil {
return err
}
// write content
item.Content = template.HTML(builder.String())
return nil
}
//go:embed "NEWS/*.md"
var newsFS embed.FS
// Items returns a list of all news items
func Items() ([]Item, error) {
var builder strings.Builder
files, err := fs.Glob(newsFS, "NEWS/*.md")
if err != nil {
return nil, err
}
items := make([]Item, len(files))
for i, file := range files {
items[i].ID = file[len("NEWS/") : len(file)-len(".md")]
if err := items[i].parse(file, &builder); err != nil {
return nil, err
}
}
slices.SortFunc(items, func(a, b Item) bool {
return !a.Date.Before(b.Date)
})
return items, nil
}
//go:embed "news.html"
var newsHTML []byte
var newsTemplate = templates.Parse[newsContext]("news.html", newsHTML, assets.AssetsDefault)
type newsContext struct {
templates.BaseContext
Items []Item
}
// HandleRoute returns the handler for the requested path
func (news *News) HandleRoute(ctx context.Context, path string) (http.Handler, error) {
tpl := newsTemplate.Prepare(news.Dependencies.Templating, templates.BaseContextGaps{
Crumbs: []component.MenuItem{
{Title: "News", Path: "/news/"},
},
})
items, itemsErr := Items()
if itemsErr != nil {
zerolog.Ctx(ctx).Err(itemsErr).Msg("Unable to load news items")
}
return tpl.HTMLHandler(func(r *http.Request) (nc newsContext, err error) {
nc.Items, err = items, itemsErr
return
}), nil
}

View file

@ -0,0 +1,18 @@
{{ template "_base.html" . }}
{{ define "title" }}News{{ end }}
{{ define "content" }}
<div class="pure-u-1">
This page contains news items from the distillery.
</div>
{{range .Items}}
<div class="pure-u-1">
<h2 id="{{.ID}}">{{.Title}}</h3>
<b>{{ .Date.Format "2006-01-02" }}</b>
{{ .Content }}
</div>
{{ end }}
{{ end }}