mirror of
https://github.com/Theodor-Springmann-Stiftung/musenalm.git
synced 2025-10-29 17:25:32 +00:00
Registration form for new users
This commit is contained in:
136
pages/user_create.go
Normal file
136
pages/user_create.go
Normal file
@@ -0,0 +1,136 @@
|
||||
package pages
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/Theodor-Springmann-Stiftung/musenalm/app"
|
||||
"github.com/Theodor-Springmann-Stiftung/musenalm/dbmodels"
|
||||
"github.com/Theodor-Springmann-Stiftung/musenalm/middleware"
|
||||
"github.com/Theodor-Springmann-Stiftung/musenalm/pagemodels"
|
||||
"github.com/Theodor-Springmann-Stiftung/musenalm/templating"
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
"github.com/pocketbase/pocketbase/tools/router"
|
||||
)
|
||||
|
||||
const (
|
||||
URL_USER_CREATE = "/user/new/"
|
||||
PATH_VALUE_ROLE = "role"
|
||||
TEMPLATE_USER_CREATE = "/user/new/"
|
||||
)
|
||||
|
||||
func init() {
|
||||
ucp := &UserCreatePage{
|
||||
StaticPage: pagemodels.StaticPage{
|
||||
Name: pagemodels.P_USER_CREATE_NAME,
|
||||
Layout: "blank",
|
||||
Template: TEMPLATE_USER_CREATE,
|
||||
URL: URL_USER_CREATE,
|
||||
},
|
||||
}
|
||||
app.Register(ucp)
|
||||
}
|
||||
|
||||
type UserCreatePage struct {
|
||||
pagemodels.StaticPage
|
||||
}
|
||||
|
||||
func (p *UserCreatePage) Setup(router *router.Router[*core.RequestEvent], app core.App, engine *templating.Engine) error {
|
||||
rg := router.Group(URL_USER_CREATE)
|
||||
rg.BindFunc(middleware.HasToken())
|
||||
rg.GET("{"+PATH_VALUE_ROLE+"}", p.GET(engine, app))
|
||||
rg.POST("{"+PATH_VALUE_ROLE+"}", p.POST(engine, app))
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *UserCreatePage) GET(engine *templating.Engine, app core.App) HandleFunc {
|
||||
return func(e *core.RequestEvent) error {
|
||||
role := e.Request.PathValue("role")
|
||||
if role != "User" && role != "Editor" && role != "Admin" {
|
||||
return engine.Response404(e, fmt.Errorf("invalid role: %s", role), nil)
|
||||
}
|
||||
|
||||
// TODO: check access token
|
||||
data := make(map[string]any)
|
||||
nonce, token, err := CSRF_CACHE.GenerateTokenBundle()
|
||||
if err != nil {
|
||||
return engine.Response500(e, err, data)
|
||||
}
|
||||
|
||||
data["role"] = role
|
||||
data["csrf_nonce"] = nonce
|
||||
data["csrf_token"] = token
|
||||
|
||||
return engine.Response200(e, p.Template, data, p.Layout)
|
||||
}
|
||||
}
|
||||
|
||||
func InvalidSignupResponse(engine *templating.Engine, e *core.RequestEvent, error string) error {
|
||||
data := make(map[string]any)
|
||||
data["error"] = error
|
||||
nonce, token, err := CSRF_CACHE.GenerateTokenBundle()
|
||||
if err != nil {
|
||||
return engine.Response500(e, err, data)
|
||||
}
|
||||
|
||||
data["csrf_nonce"] = nonce
|
||||
data["csrf_token"] = token
|
||||
str, err := engine.RenderToString(e, data, TEMPLATE_USER_CREATE, "blank")
|
||||
if err != nil {
|
||||
return engine.Response500(e, err, data)
|
||||
}
|
||||
|
||||
return e.HTML(400, str)
|
||||
}
|
||||
|
||||
func (p *UserCreatePage) POST(engine *templating.Engine, app core.App) HandleFunc {
|
||||
return func(e *core.RequestEvent) error {
|
||||
role := e.Request.PathValue("role")
|
||||
if role != "User" && role != "Editor" && role != "Admin" {
|
||||
return engine.Response404(e, fmt.Errorf("invalid role: %s", role), nil)
|
||||
}
|
||||
|
||||
// TODO: check access token
|
||||
data := make(map[string]any)
|
||||
data["role"] = role
|
||||
|
||||
formdata := struct {
|
||||
Username string `form:"username"`
|
||||
Password string `form:"password"`
|
||||
PasswordRepeat string `form:"password_repeat"`
|
||||
Name string `form:"name"`
|
||||
CsrfNonce string `form:"csrf_nonce"`
|
||||
CsrfToken string `form:"csrf_token"`
|
||||
}{}
|
||||
|
||||
if err := e.BindBody(&formdata); err != nil {
|
||||
return engine.Response500(e, err, data)
|
||||
}
|
||||
|
||||
data["formdata"] = formdata
|
||||
|
||||
if _, err := CSRF_CACHE.ValidateTokenBundle(formdata.CsrfNonce, formdata.CsrfToken); err != nil {
|
||||
return InvalidSignupResponse(engine, e, "CSRF-Token ungültig.")
|
||||
}
|
||||
|
||||
if formdata.Username == "" || formdata.Password == "" || formdata.Name == "" {
|
||||
return InvalidSignupResponse(engine, e, "Bitte alle Felder ausfüllen.")
|
||||
}
|
||||
|
||||
if formdata.Password != formdata.PasswordRepeat {
|
||||
return InvalidSignupResponse(engine, e, "Passwörter stimmen nicht überein.")
|
||||
}
|
||||
|
||||
_, err := app.FindAuthRecordByEmail(dbmodels.USERS_TABLE, formdata.Username)
|
||||
if err == nil {
|
||||
return InvalidSignupResponse(engine, e, "Benutzer existiert bereits.")
|
||||
}
|
||||
|
||||
user, err := dbmodels.CreateUser(app, formdata.Username, formdata.Password, formdata.Name, role)
|
||||
if err != nil {
|
||||
return InvalidSignupResponse(engine, e, fmt.Sprintf("Fehler beim Erstellen des Benutzers: %s", err.Error()))
|
||||
}
|
||||
|
||||
data["user"] = user
|
||||
return engine.Response200(e, p.Template, data, p.Layout)
|
||||
}
|
||||
}
|
||||
119
pages/user_management_access.go
Normal file
119
pages/user_management_access.go
Normal file
@@ -0,0 +1,119 @@
|
||||
package pages
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/Theodor-Springmann-Stiftung/musenalm/app"
|
||||
"github.com/Theodor-Springmann-Stiftung/musenalm/dbmodels"
|
||||
"github.com/Theodor-Springmann-Stiftung/musenalm/middleware"
|
||||
"github.com/Theodor-Springmann-Stiftung/musenalm/pagemodels"
|
||||
"github.com/Theodor-Springmann-Stiftung/musenalm/templating"
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
"github.com/pocketbase/pocketbase/tools/router"
|
||||
)
|
||||
|
||||
const (
|
||||
URL_USER_MANAGEMENT_ACCESS = "/user/management/access/"
|
||||
TEMPLATE_USER_MANAGEMENT_ACCESS = "/user/management/access/"
|
||||
)
|
||||
|
||||
func init() {
|
||||
ump := &UserManagementAccessPage{
|
||||
StaticPage: pagemodels.StaticPage{
|
||||
Name: pagemodels.P_USER_MGMT_ACCESS_NAME,
|
||||
Layout: "blank",
|
||||
Template: TEMPLATE_USER_MANAGEMENT_ACCESS,
|
||||
URL: URL_USER_MANAGEMENT_ACCESS,
|
||||
},
|
||||
}
|
||||
app.Register(ump)
|
||||
}
|
||||
|
||||
type UserManagementAccessPage struct {
|
||||
pagemodels.StaticPage
|
||||
}
|
||||
|
||||
func (p *UserManagementAccessPage) Setup(router *router.Router[*core.RequestEvent], app core.App, engine *templating.Engine) error {
|
||||
rg := router.Group(URL_USER_MANAGEMENT_ACCESS)
|
||||
rg.BindFunc(middleware.IsAdmin())
|
||||
rg.GET("{"+PATH_VALUE_ROLE+"}", p.GET(engine, app))
|
||||
rg.POST("{"+PATH_VALUE_ROLE+"}", p.POST(engine, app))
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *UserManagementAccessPage) GET(engine *templating.Engine, app core.App) HandleFunc {
|
||||
return func(e *core.RequestEvent) error {
|
||||
role := e.Request.PathValue("role")
|
||||
if role != "User" && role != "Editor" && role != "Admin" {
|
||||
return engine.Response404(e, fmt.Errorf("invalid role: %s", role), nil)
|
||||
}
|
||||
|
||||
path_access := URL_USER_CREATE + role
|
||||
record, err := app.FindFirstRecordByData(dbmodels.ACCESS_TOKENS_TABLE, dbmodels.ACCESS_TOKENS_URL_FIELD, path_access)
|
||||
var access_token *dbmodels.AccessToken
|
||||
if err != nil {
|
||||
token, err := dbmodels.CreateAccessToken(app, "", path_access, 7*24*time.Hour)
|
||||
if err != nil {
|
||||
return engine.Response500(e, err, nil)
|
||||
}
|
||||
access_token = token
|
||||
} else {
|
||||
access_token = dbmodels.NewAccessToken(record)
|
||||
}
|
||||
|
||||
// TODO: check if access token exists, if not generate
|
||||
data := make(map[string]any)
|
||||
data["role"] = role
|
||||
data["access_url"] = "https://musenalm.de" + path_access + "?token=" + access_token.Token()
|
||||
data["relative_url"] = path_access + "?token=" + access_token.Token()
|
||||
data["validUntil"] = access_token.Expires().Time().Local().Format("02.01.2006 15:04")
|
||||
|
||||
nonce, token, err := CSRF_CACHE.GenerateTokenBundle()
|
||||
if err != nil {
|
||||
return engine.Response500(e, err, data)
|
||||
}
|
||||
data["csrf_nonce"] = nonce
|
||||
data["csrf_token"] = token
|
||||
|
||||
redirect_url := e.Request.URL.Query().Get("redirectTo")
|
||||
if redirect_url != "" {
|
||||
data["redirect_url"] = redirect_url
|
||||
}
|
||||
|
||||
return engine.Response200(e, p.Template, data, p.Layout)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *UserManagementAccessPage) POST(engine *templating.Engine, app core.App) HandleFunc {
|
||||
return func(e *core.RequestEvent) error {
|
||||
role := e.Request.PathValue("role")
|
||||
if role != "User" && role != "Editor" && role != "Admin" {
|
||||
return engine.Response404(e, fmt.Errorf("invalid role: %s", role), nil)
|
||||
}
|
||||
|
||||
path_access := URL_USER_CREATE + role
|
||||
record, err := app.FindFirstRecordByData(dbmodels.ACCESS_TOKENS_TABLE, dbmodels.ACCESS_TOKENS_URL_FIELD, path_access)
|
||||
if err == nil {
|
||||
go app.Delete(record)
|
||||
}
|
||||
|
||||
token, err := dbmodels.CreateAccessToken(app, "", path_access, 7*24*time.Hour)
|
||||
if err != nil {
|
||||
return engine.Response500(e, err, nil)
|
||||
}
|
||||
|
||||
data := make(map[string]any)
|
||||
data["role"] = role
|
||||
data["access_url"] = "https://musenalm.de" + path_access + "?token=" + token.Token()
|
||||
data["relative_url"] = path_access + "?token=" + token.Token()
|
||||
data["validUntil"] = token.Expires().Time().Format("02.01.2006 15:04")
|
||||
|
||||
redirect_url := e.Request.URL.Query().Get("redirectTo")
|
||||
if redirect_url != "" {
|
||||
data["redirect_url"] = redirect_url
|
||||
}
|
||||
|
||||
return engine.Response200(e, p.Template, data, p.Layout)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user