142 lines
4.2 KiB
Go
142 lines
4.2 KiB
Go
package panel
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
|
|
"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/auth/next"
|
|
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/auth/policy"
|
|
"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/ssh2/sshkeys"
|
|
"github.com/FAU-CDI/wisski-distillery/internal/models"
|
|
"github.com/julienschmidt/httprouter"
|
|
"github.com/tkw1536/pkglib/httpx"
|
|
)
|
|
|
|
type UserPanel struct {
|
|
component.Base
|
|
Dependencies struct {
|
|
Auth *auth.Auth
|
|
Templating *templating.Templating
|
|
Policy *policy.Policy
|
|
Instances *instances.Instances
|
|
Next *next.Next
|
|
Keys *sshkeys.SSHKeys
|
|
}
|
|
}
|
|
|
|
var (
|
|
_ component.Routeable = (*UserPanel)(nil)
|
|
_ component.Menuable = (*UserPanel)(nil)
|
|
)
|
|
|
|
func (panel *UserPanel) Routes() component.Routes {
|
|
return component.Routes{
|
|
Prefix: "/user/",
|
|
CSRF: true,
|
|
Decorator: panel.Dependencies.Auth.Require(nil),
|
|
}
|
|
}
|
|
|
|
func (panel *UserPanel) Menu(r *http.Request) []component.MenuItem {
|
|
title := "Login"
|
|
|
|
user, err := panel.Dependencies.Auth.UserOf(r)
|
|
if user != nil && err == nil {
|
|
title = user.User.User
|
|
}
|
|
return []component.MenuItem{
|
|
{Title: title, Priority: component.MenuUser, Path: "/user/"},
|
|
}
|
|
}
|
|
|
|
var (
|
|
menuUser = component.MenuItem{Title: "User", Path: "/user/"}
|
|
menuChangePassword = component.MenuItem{Title: "Change Password", Path: "/user/password/"}
|
|
menuSSH = component.MenuItem{Title: "SSH Keys", Path: "/user/ssh/"}
|
|
menuSSHAdd = component.MenuItem{Title: "Add New Key", Path: "/user/ssh/add/"}
|
|
|
|
menuTOTPAction = component.DummyMenuItem()
|
|
menuTOTPDisable = component.MenuItem{Title: "Disable Passcode (TOTP)", Path: "/user/totp/disable/"}
|
|
menuTOTPEnable = component.MenuItem{Title: "Enable Passcode (TOTP)", Path: "/user/totp/enable/"}
|
|
)
|
|
|
|
func (panel *UserPanel) HandleRoute(ctx context.Context, route string) (http.Handler, error) {
|
|
router := httprouter.New()
|
|
|
|
{
|
|
user := panel.routeUser(ctx)
|
|
router.Handler(http.MethodGet, route, user)
|
|
}
|
|
|
|
{
|
|
password := panel.routePassword(ctx)
|
|
router.Handler(http.MethodGet, route+"password", password)
|
|
router.Handler(http.MethodPost, route+"password", password)
|
|
}
|
|
|
|
{
|
|
totpenable := panel.routeTOTPEnable(ctx)
|
|
router.Handler(http.MethodGet, route+"totp/enable", totpenable)
|
|
router.Handler(http.MethodPost, route+"totp/enable", totpenable)
|
|
}
|
|
|
|
{
|
|
totpenroll := panel.routeTOTPEnroll(ctx)
|
|
router.Handler(http.MethodGet, route+"totp/enroll", totpenroll)
|
|
router.Handler(http.MethodPost, route+"totp/enroll", totpenroll)
|
|
}
|
|
|
|
{
|
|
totpdisable := panel.routeTOTPDisable(ctx)
|
|
router.Handler(http.MethodGet, route+"totp/disable", totpdisable)
|
|
router.Handler(http.MethodPost, route+"totp/disable", totpdisable)
|
|
}
|
|
|
|
{
|
|
ssh := panel.sshRoute(ctx)
|
|
router.Handler(http.MethodGet, route+"ssh", ssh)
|
|
}
|
|
|
|
{
|
|
add := panel.sshAddRoute(ctx)
|
|
router.Handler(http.MethodGet, route+"ssh/add", add)
|
|
router.Handler(http.MethodPost, route+"ssh/add", add)
|
|
}
|
|
|
|
{
|
|
delete := panel.sshDeleteRoute(ctx)
|
|
router.Handler(http.MethodPost, route+"ssh/delete", delete)
|
|
}
|
|
|
|
// ensure that the user is logged in!
|
|
return panel.Dependencies.Auth.Protect(router, nil), nil
|
|
}
|
|
|
|
type userFormContext struct {
|
|
templating.RuntimeFlags
|
|
httpx.FormContext
|
|
|
|
User *models.User
|
|
}
|
|
|
|
func (panel *UserPanel) UserFormContext(tpl *templating.Template[userFormContext], last component.MenuItem, funcs ...templating.FlagFunc) func(ctx httpx.FormContext, r *http.Request) any {
|
|
funcs = append(funcs, func(flags templating.Flags, r *http.Request) templating.Flags {
|
|
// append the last menu item, and prepend the menuUser one!
|
|
flags.Crumbs = append(flags.Crumbs, last, last)
|
|
copy(flags.Crumbs[1:], flags.Crumbs)
|
|
flags.Crumbs[0] = menuUser
|
|
return flags
|
|
})
|
|
|
|
return func(ctx httpx.FormContext, r *http.Request) any {
|
|
uctx := userFormContext{FormContext: ctx}
|
|
if user, err := panel.Dependencies.Auth.UserOf(r); err == nil {
|
|
uctx.User = &user.User
|
|
}
|
|
return tpl.Context(r, uctx, funcs...)
|
|
}
|
|
}
|