Refactor server and templates package
This commit is contained in:
parent
b6bf0a8900
commit
6ede99d7c6
105 changed files with 341 additions and 339 deletions
7
internal/dis/component/server/news/NEWS/2022-09-08-go.md
Normal file
7
internal/dis/component/server/news/NEWS/2022-09-08-go.md
Normal 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
|
||||
10
internal/dis/component/server/news/NEWS/2022-09-09-admin.md
Normal file
10
internal/dis/component/server/news/NEWS/2022-09-09-admin.md
Normal 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
|
||||
|
|
@ -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.
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
title: Login using Distillery Administration
|
||||
date: 2022-11-23
|
||||
---
|
||||
|
||||
- The admin interface now allows login to individual user accounts
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
title: Automatic Password Checking
|
||||
date: 2022-11-25
|
||||
---
|
||||
|
||||
- Implemented automatic password checking
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
140
internal/dis/component/server/news/news.go
Normal file
140
internal/dis/component/server/news/news.go
Normal 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
|
||||
}
|
||||
18
internal/dis/component/server/news/news.html
Normal file
18
internal/dis/component/server/news/news.html
Normal 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 }}
|
||||
Loading…
Add table
Add a link
Reference in a new issue