diff --git a/internal/web/context/context.go b/internal/web/context/context.go index 208fc07..d31c4f8 100644 --- a/internal/web/context/context.go +++ b/internal/web/context/context.go @@ -13,7 +13,7 @@ import ( "sync" ) -type OGContext struct { +type Context struct { echo.Context data echo.Map @@ -23,33 +23,33 @@ type OGContext struct { User *db.User } -func NewContext(c echo.Context, sessionPath string) *OGContext { - return &OGContext{ +func NewContext(c echo.Context, sessionPath string) *Context { + return &Context{ Context: c, data: make(echo.Map), store: NewStore(sessionPath), } } -func (ctx *OGContext) SetData(key string, value any) { +func (ctx *Context) SetData(key string, value any) { ctx.lock.Lock() defer ctx.lock.Unlock() ctx.data[key] = value } -func (ctx *OGContext) GetData(key string) any { +func (ctx *Context) GetData(key string) any { ctx.lock.RLock() defer ctx.lock.RUnlock() return ctx.data[key] } -func (ctx *OGContext) DataMap() echo.Map { +func (ctx *Context) DataMap() echo.Map { return ctx.data } -func (ctx *OGContext) ErrorRes(code int, message string, err error) error { +func (ctx *Context) ErrorRes(code int, message string, err error) error { if code >= 500 { var skipLogger = log.With().CallerWithSkipFrameCount(3).Logger() skipLogger.Error().Err(err).Msg(message) @@ -60,36 +60,36 @@ func (ctx *OGContext) ErrorRes(code int, message string, err error) error { return &echo.HTTPError{Code: code, Message: message, Internal: err} } -func (ctx *OGContext) RedirectTo(location string) error { +func (ctx *Context) RedirectTo(location string) error { return ctx.Context.Redirect(302, config.C.ExternalUrl+location) } -func (ctx *OGContext) HTML_(template string) error { +func (ctx *Context) HTML_(template string) error { return ctx.HtmlWithCode(200, template) } -func (ctx *OGContext) HtmlWithCode(code int, template string) error { +func (ctx *Context) HtmlWithCode(code int, template string) error { ctx.setErrorFlashes() return ctx.Render(code, template, ctx.DataMap()) } -func (ctx *OGContext) JSON_(data any) error { +func (ctx *Context) JSON_(data any) error { return ctx.JsonWithCode(200, data) } -func (ctx *OGContext) JsonWithCode(code int, data any) error { +func (ctx *Context) JsonWithCode(code int, data any) error { return ctx.JSON(code, data) } -func (ctx *OGContext) PlainText(code int, message string) error { +func (ctx *Context) PlainText(code int, message string) error { return ctx.String(code, message) } -func (ctx *OGContext) NotFound(message string) error { +func (ctx *Context) NotFound(message string) error { return ctx.ErrorRes(404, message, nil) } -func (ctx *OGContext) setErrorFlashes() { +func (ctx *Context) setErrorFlashes() { sess, _ := ctx.store.flashStore.Get(ctx.Request(), "flash") ctx.SetData("flashErrors", sess.Flashes("error")) @@ -99,28 +99,28 @@ func (ctx *OGContext) setErrorFlashes() { _ = sess.Save(ctx.Request(), ctx.Response()) } -func (ctx *OGContext) GetSession() *sessions.Session { +func (ctx *Context) GetSession() *sessions.Session { sess, _ := ctx.store.UserStore.Get(ctx.Request(), "session") return sess } -func (ctx *OGContext) SaveSession(sess *sessions.Session) { +func (ctx *Context) SaveSession(sess *sessions.Session) { _ = sess.Save(ctx.Request(), ctx.Response()) } -func (ctx *OGContext) DeleteSession() { +func (ctx *Context) DeleteSession() { sess := ctx.GetSession() sess.Options.MaxAge = -1 ctx.SaveSession(sess) } -func (ctx *OGContext) AddFlash(flashMessage string, flashType string) { +func (ctx *Context) AddFlash(flashMessage string, flashType string) { sess, _ := ctx.store.flashStore.Get(ctx.Request(), "flash") sess.AddFlash(flashMessage, flashType) _ = sess.Save(ctx.Request(), ctx.Response()) } -func (ctx *OGContext) getUserLogged() *db.User { +func (ctx *Context) getUserLogged() *db.User { user := ctx.GetData("userLogged") if user != nil { return user.(*db.User) @@ -128,16 +128,16 @@ func (ctx *OGContext) getUserLogged() *db.User { return nil } -func (ctx *OGContext) DeleteCsrfCookie() { +func (ctx *Context) DeleteCsrfCookie() { ctx.SetCookie(&http.Cookie{Name: "_csrf", Path: "/", MaxAge: -1}) } -func (ctx *OGContext) TrH(key string, args ...any) template.HTML { +func (ctx *Context) TrH(key string, args ...any) template.HTML { l := ctx.GetData("locale").(*i18n.Locale) return l.Tr(key, args...) } -func (ctx *OGContext) Tr(key string, args ...any) string { +func (ctx *Context) Tr(key string, args ...any) string { l := ctx.GetData("locale").(*i18n.Locale) return l.String(key, args...) } diff --git a/internal/web/handler/admin.go b/internal/web/handlers/admin.go similarity index 87% rename from internal/web/handler/admin.go rename to internal/web/handlers/admin.go index 30b2991..71a6202 100644 --- a/internal/web/handler/admin.go +++ b/internal/web/handlers/admin.go @@ -1,4 +1,4 @@ -package handler +package handlers import ( "github.com/thomiceli/opengist/internal/actions" @@ -11,7 +11,7 @@ import ( "time" ) -func AdminIndex(ctx *context.OGContext) error { +func AdminIndex(ctx *context.Context) error { ctx.SetData("htmlTitle", ctx.TrH("admin.admin_panel")) ctx.SetData("adminHeaderPage", "index") @@ -50,7 +50,7 @@ func AdminIndex(ctx *context.OGContext) error { return ctx.HTML_("admin_index.html") } -func AdminUsers(ctx *context.OGContext) error { +func AdminUsers(ctx *context.Context) error { ctx.SetData("htmlTitle", ctx.TrH("admin.users")+" - "+ctx.TrH("admin.admin_panel")) ctx.SetData("adminHeaderPage", "users") ctx.SetData("loadStartTime", time.Now()) @@ -70,7 +70,7 @@ func AdminUsers(ctx *context.OGContext) error { return ctx.HTML_("admin_users.html") } -func AdminGists(ctx *context.OGContext) error { +func AdminGists(ctx *context.Context) error { ctx.SetData("htmlTitle", ctx.TrH("admin.gists")+" - "+ctx.TrH("admin.admin_panel")) ctx.SetData("adminHeaderPage", "gists") pageInt := getPage(ctx) @@ -88,7 +88,7 @@ func AdminGists(ctx *context.OGContext) error { return ctx.HTML_("admin_gists.html") } -func AdminUserDelete(ctx *context.OGContext) error { +func AdminUserDelete(ctx *context.Context) error { userId, _ := strconv.ParseUint(ctx.Param("user"), 10, 64) user, err := db.GetUserById(uint(userId)) if err != nil { @@ -103,7 +103,7 @@ func AdminUserDelete(ctx *context.OGContext) error { return ctx.RedirectTo("/admin-panel/users") } -func AdminGistDelete(ctx *context.OGContext) error { +func AdminGistDelete(ctx *context.Context) error { gist, err := db.GetGistByID(ctx.Param("gist")) if err != nil { return ctx.ErrorRes(500, "Cannot retrieve gist", err) @@ -123,43 +123,43 @@ func AdminGistDelete(ctx *context.OGContext) error { return ctx.RedirectTo("/admin-panel/gists") } -func AdminSyncReposFromFS(ctx *context.OGContext) error { +func AdminSyncReposFromFS(ctx *context.Context) error { ctx.AddFlash(ctx.Tr("flash.admin.sync-fs"), "success") go actions.Run(actions.SyncReposFromFS) return ctx.RedirectTo("/admin-panel") } -func AdminSyncReposFromDB(ctx *context.OGContext) error { +func AdminSyncReposFromDB(ctx *context.Context) error { ctx.AddFlash(ctx.Tr("flash.admin.sync-db"), "success") go actions.Run(actions.SyncReposFromDB) return ctx.RedirectTo("/admin-panel") } -func AdminGcRepos(ctx *context.OGContext) error { +func AdminGcRepos(ctx *context.Context) error { ctx.AddFlash(ctx.Tr("flash.admin.git-gc"), "success") go actions.Run(actions.GitGcRepos) return ctx.RedirectTo("/admin-panel") } -func AdminSyncGistPreviews(ctx *context.OGContext) error { +func AdminSyncGistPreviews(ctx *context.Context) error { ctx.AddFlash(ctx.Tr("flash.admin.sync-previews"), "success") go actions.Run(actions.SyncGistPreviews) return ctx.RedirectTo("/admin-panel") } -func AdminResetHooks(ctx *context.OGContext) error { +func AdminResetHooks(ctx *context.Context) error { ctx.AddFlash(ctx.Tr("flash.admin.reset-hooks"), "success") go actions.Run(actions.ResetHooks) return ctx.RedirectTo("/admin-panel") } -func AdminIndexGists(ctx *context.OGContext) error { +func AdminIndexGists(ctx *context.Context) error { ctx.AddFlash(ctx.Tr("flash.admin.index-gists"), "success") go actions.Run(actions.IndexGists) return ctx.RedirectTo("/admin-panel") } -func AdminConfig(ctx *context.OGContext) error { +func AdminConfig(ctx *context.Context) error { ctx.SetData("htmlTitle", ctx.TrH("admin.configuration")+" - "+ctx.TrH("admin.admin_panel")) ctx.SetData("adminHeaderPage", "config") @@ -169,7 +169,7 @@ func AdminConfig(ctx *context.OGContext) error { return ctx.HTML_("admin_config.html") } -func AdminSetConfig(ctx *context.OGContext) error { +func AdminSetConfig(ctx *context.Context) error { key := ctx.FormValue("key") value := ctx.FormValue("value") @@ -182,7 +182,7 @@ func AdminSetConfig(ctx *context.OGContext) error { }) } -func AdminInvitations(ctx *context.OGContext) error { +func AdminInvitations(ctx *context.Context) error { ctx.SetData("htmlTitle", ctx.TrH("admin.invitations")+" - "+ctx.TrH("admin.admin_panel")) ctx.SetData("adminHeaderPage", "invitations") @@ -196,7 +196,7 @@ func AdminInvitations(ctx *context.OGContext) error { return ctx.HTML_("admin_invitations.html") } -func AdminInvitationsCreate(ctx *context.OGContext) error { +func AdminInvitationsCreate(ctx *context.Context) error { code := ctx.FormValue("code") nbMax, err := strconv.ParseUint(ctx.FormValue("nbMax"), 10, 64) if err != nil { @@ -222,7 +222,7 @@ func AdminInvitationsCreate(ctx *context.OGContext) error { return ctx.RedirectTo("/admin-panel/invitations") } -func AdminInvitationsDelete(ctx *context.OGContext) error { +func AdminInvitationsDelete(ctx *context.Context) error { id, _ := strconv.ParseUint(ctx.Param("id"), 10, 64) invitation, err := db.GetInvitationByID(uint(id)) if err != nil { diff --git a/internal/web/handler/auth.go b/internal/web/handlers/auth.go similarity index 95% rename from internal/web/handler/auth.go rename to internal/web/handlers/auth.go index 945f140..84a1259 100644 --- a/internal/web/handler/auth.go +++ b/internal/web/handlers/auth.go @@ -1,4 +1,4 @@ -package handler +package handlers import ( "bytes" @@ -37,7 +37,7 @@ const ( OpenIDConnect = "openid-connect" ) -func Register(ctx *context.OGContext) error { +func Register(ctx *context.Context) error { disableSignup := ctx.GetData("DisableSignup") disableForm := ctx.GetData("DisableLoginForm") @@ -58,7 +58,7 @@ func Register(ctx *context.OGContext) error { return ctx.HTML_("auth_form.html") } -func ProcessRegister(ctx *context.OGContext) error { +func ProcessRegister(ctx *context.Context) error { disableSignup := ctx.GetData("DisableSignup") code := ctx.QueryParam("code") @@ -127,7 +127,7 @@ func ProcessRegister(ctx *context.OGContext) error { return ctx.RedirectTo("/") } -func Login(ctx *context.OGContext) error { +func Login(ctx *context.Context) error { ctx.SetData("title", ctx.TrH("auth.login")) ctx.SetData("htmlTitle", ctx.TrH("auth.login")) ctx.SetData("disableForm", ctx.GetData("DisableLoginForm")) @@ -135,7 +135,7 @@ func Login(ctx *context.OGContext) error { return ctx.HTML_("auth_form.html") } -func ProcessLogin(ctx *context.OGContext) error { +func ProcessLogin(ctx *context.Context) error { if ctx.GetData("DisableLoginForm") == true { return ctx.ErrorRes(403, ctx.Tr("error.login-disabled-form"), nil) } @@ -189,7 +189,7 @@ func ProcessLogin(ctx *context.OGContext) error { return ctx.RedirectTo("/") } -func Mfa(ctx *context.OGContext) error { +func Mfa(ctx *context.Context) error { var err error user := db.User{ID: ctx.GetSession().Values["mfaID"].(uint)} @@ -205,7 +205,7 @@ func Mfa(ctx *context.OGContext) error { return ctx.HTML_("mfa.html") } -func OauthCallback(ctx *context.OGContext) error { +func OauthCallback(ctx *context.Context) error { user, err := gothic.CompleteUserAuth(ctx.Response(), ctx.Request()) if err != nil { return ctx.ErrorRes(400, ctx.Tr("error.complete-oauth-login", err.Error()), err) @@ -311,7 +311,7 @@ func OauthCallback(ctx *context.OGContext) error { return ctx.RedirectTo("/") } -func Oauth(ctx *context.OGContext) error { +func Oauth(ctx *context.Context) error { provider := ctx.Param("provider") httpProtocol := "http" @@ -401,7 +401,7 @@ func Oauth(ctx *context.OGContext) error { return nil } -func OauthUnlink(ctx *context.OGContext) error { +func OauthUnlink(ctx *context.Context) error { provider := ctx.Param("provider") currUser := ctx.User @@ -425,7 +425,7 @@ func OauthUnlink(ctx *context.OGContext) error { return ctx.RedirectTo("/settings") } -func BeginWebAuthnBinding(ctx *context.OGContext) error { +func BeginWebAuthnBinding(ctx *context.Context) error { credsCreation, jsonWaSession, err := webauthn.BeginBinding(ctx.User) if err != nil { return ctx.ErrorRes(500, "Cannot begin WebAuthn registration", err) @@ -439,7 +439,7 @@ func BeginWebAuthnBinding(ctx *context.OGContext) error { return ctx.JSON(200, credsCreation) } -func FinishWebAuthnBinding(ctx *context.OGContext) error { +func FinishWebAuthnBinding(ctx *context.Context) error { sess := ctx.GetSession() jsonWaSession, ok := sess.Values["webauthn_registration_session"].([]byte) if !ok { @@ -483,7 +483,7 @@ func FinishWebAuthnBinding(ctx *context.OGContext) error { return ctx.JSON_([]string{"OK"}) } -func BeginWebAuthnLogin(ctx *context.OGContext) error { +func BeginWebAuthnLogin(ctx *context.Context) error { credsCreation, jsonWaSession, err := webauthn.BeginDiscoverableLogin() if err != nil { return ctx.ErrorRes(401, "Cannot begin WebAuthn login", err) @@ -497,7 +497,7 @@ func BeginWebAuthnLogin(ctx *context.OGContext) error { return ctx.JSON_(credsCreation) } -func FinishWebAuthnLogin(ctx *context.OGContext) error { +func FinishWebAuthnLogin(ctx *context.Context) error { sess := ctx.GetSession() sessionData, ok := sess.Values["webauthn_login_session"].([]byte) if !ok { @@ -518,7 +518,7 @@ func FinishWebAuthnLogin(ctx *context.OGContext) error { return ctx.JSON_([]string{"OK"}) } -func BeginWebAuthnAssertion(ctx *context.OGContext) error { +func BeginWebAuthnAssertion(ctx *context.Context) error { sess := ctx.GetSession() ogUser, err := db.GetUserById(sess.Values["mfaID"].(uint)) @@ -538,7 +538,7 @@ func BeginWebAuthnAssertion(ctx *context.OGContext) error { return ctx.JSON_(credsCreation) } -func FinishWebAuthnAssertion(ctx *context.OGContext) error { +func FinishWebAuthnAssertion(ctx *context.Context) error { sess := ctx.GetSession() sessionData, ok := sess.Values["webauthn_assertion_session"].([]byte) if !ok { @@ -566,7 +566,7 @@ func FinishWebAuthnAssertion(ctx *context.OGContext) error { return ctx.JSON_([]string{"OK"}) } -func BeginTotp(ctx *context.OGContext) error { +func BeginTotp(ctx *context.Context) error { user := ctx.User if _, hasTotp, err := user.HasMFA(); err != nil { @@ -599,7 +599,7 @@ func BeginTotp(ctx *context.OGContext) error { } -func FinishTotp(ctx *context.OGContext) error { +func FinishTotp(ctx *context.Context) error { user := ctx.User if _, hasTotp, err := user.HasMFA(); err != nil { @@ -656,7 +656,7 @@ func FinishTotp(ctx *context.OGContext) error { return ctx.HTML_("totp.html") } -func AssertTotp(ctx *context.OGContext) error { +func AssertTotp(ctx *context.Context) error { var err error dto := &db.TOTPDTO{} if err := ctx.Bind(dto); err != nil { @@ -704,7 +704,7 @@ func AssertTotp(ctx *context.OGContext) error { return ctx.RedirectTo(redirectUrl) } -func DisableTotp(ctx *context.OGContext) error { +func DisableTotp(ctx *context.Context) error { user := ctx.User userTotp, err := db.GetTOTPByUserID(user.ID) if err != nil { @@ -719,7 +719,7 @@ func DisableTotp(ctx *context.OGContext) error { return ctx.RedirectTo("/settings") } -func RegenerateTotpRecoveryCodes(ctx *context.OGContext) error { +func RegenerateTotpRecoveryCodes(ctx *context.Context) error { user := ctx.User userTotp, err := db.GetTOTPByUserID(user.ID) if err != nil { @@ -735,7 +735,7 @@ func RegenerateTotpRecoveryCodes(ctx *context.OGContext) error { return ctx.HTML_("totp.html") } -func Logout(ctx *context.OGContext) error { +func Logout(ctx *context.Context) error { ctx.DeleteSession() ctx.DeleteCsrfCookie() return ctx.RedirectTo("/all") @@ -803,7 +803,7 @@ func getAvatarUrlFromProvider(provider string, identifier string) string { } type ContextAuthInfo struct { - Context *context.OGContext + Context *context.Context } func (auth ContextAuthInfo) RequireLogin() (bool, error) { diff --git a/internal/web/handler/gist.go b/internal/web/handlers/gist.go similarity index 95% rename from internal/web/handler/gist.go rename to internal/web/handlers/gist.go index 55bd28a..720bcb5 100644 --- a/internal/web/handler/gist.go +++ b/internal/web/handlers/gist.go @@ -1,4 +1,4 @@ -package handler +package handlers import ( "archive/zip" @@ -27,7 +27,7 @@ import ( "gorm.io/gorm" ) -func AllGists(ctx *context.OGContext) error { +func AllGists(ctx *context.Context) error { var err error var urlPage string @@ -158,7 +158,7 @@ func AllGists(ctx *context.OGContext) error { return ctx.HTML_("all.html") } -func Search(ctx *context.OGContext) error { +func Search(ctx *context.Context) error { var err error content, meta := ParseSearchQueryStr(ctx.QueryParam("q")) @@ -221,7 +221,7 @@ func Search(ctx *context.OGContext) error { return ctx.HTML_("search.html") } -func GistIndex(ctx *context.OGContext) error { +func GistIndex(ctx *context.Context) error { if ctx.GetData("gistpage") == "js" { return GistJs(ctx) } else if ctx.GetData("gistpage") == "json" { @@ -252,7 +252,7 @@ func GistIndex(ctx *context.OGContext) error { return ctx.HTML_("gist.html") } -func GistJson(ctx *context.OGContext) error { +func GistJson(ctx *context.Context) error { gist := ctx.GetData("gist").(*db.Gist) files, err := gist.Files("HEAD", true) if err != nil { @@ -297,7 +297,7 @@ func GistJson(ctx *context.OGContext) error { }) } -func GistJs(ctx *context.OGContext) error { +func GistJs(ctx *context.Context) error { if _, exists := ctx.QueryParams()["dark"]; exists { ctx.SetData("dark", "dark") } @@ -331,7 +331,7 @@ func GistJs(ctx *context.OGContext) error { return ctx.PlainText(200, js) } -func Revisions(ctx *context.OGContext) error { +func Revisions(ctx *context.Context) error { gist := ctx.GetData("gist").(*db.Gist) userName := gist.User.Username gistName := gist.Identifier() @@ -368,12 +368,12 @@ func Revisions(ctx *context.OGContext) error { return ctx.HTML_("revisions.html") } -func Create(ctx *context.OGContext) error { +func Create(ctx *context.Context) error { ctx.SetData("htmlTitle", ctx.TrH("gist.new.create-a-new-gist")) return ctx.HTML_("create.html") } -func ProcessCreate(ctx *context.OGContext) error { +func ProcessCreate(ctx *context.Context) error { isCreate := false if ctx.Request().URL.Path == "/" { isCreate = true @@ -497,7 +497,7 @@ func ProcessCreate(ctx *context.OGContext) error { return ctx.RedirectTo("/" + user.Username + "/" + gist.Identifier()) } -func EditVisibility(ctx *context.OGContext) error { +func EditVisibility(ctx *context.Context) error { gist := ctx.GetData("gist").(*db.Gist) dto := new(db.VisibilityDTO) @@ -514,7 +514,7 @@ func EditVisibility(ctx *context.OGContext) error { return ctx.RedirectTo("/" + gist.User.Username + "/" + gist.Identifier()) } -func DeleteGist(ctx *context.OGContext) error { +func DeleteGist(ctx *context.Context) error { gist := ctx.GetData("gist").(*db.Gist) if err := gist.Delete(); err != nil { @@ -526,7 +526,7 @@ func DeleteGist(ctx *context.OGContext) error { return ctx.RedirectTo("/") } -func Like(ctx *context.OGContext) error { +func Like(ctx *context.Context) error { gist := ctx.GetData("gist").(*db.Gist) currentUser := ctx.User @@ -552,7 +552,7 @@ func Like(ctx *context.OGContext) error { return ctx.RedirectTo(redirectTo) } -func Fork(ctx *context.OGContext) error { +func Fork(ctx *context.Context) error { gist := ctx.GetData("gist").(*db.Gist) currentUser := ctx.User @@ -603,7 +603,7 @@ func Fork(ctx *context.OGContext) error { return ctx.RedirectTo("/" + currentUser.Username + "/" + newGist.Identifier()) } -func RawFile(ctx *context.OGContext) error { +func RawFile(ctx *context.Context) error { gist := ctx.GetData("gist").(*db.Gist) file, err := gist.File(ctx.Param("revision"), ctx.Param("file"), false) if err != nil { @@ -617,7 +617,7 @@ func RawFile(ctx *context.OGContext) error { return ctx.PlainText(200, file.Content) } -func DownloadFile(ctx *context.OGContext) error { +func DownloadFile(ctx *context.Context) error { gist := ctx.GetData("gist").(*db.Gist) file, err := gist.File(ctx.Param("revision"), ctx.Param("file"), false) if err != nil { @@ -639,7 +639,7 @@ func DownloadFile(ctx *context.OGContext) error { return nil } -func Edit(ctx *context.OGContext) error { +func Edit(ctx *context.Context) error { gist := ctx.GetData("gist").(*db.Gist) files, err := gist.Files("HEAD", false) @@ -653,7 +653,7 @@ func Edit(ctx *context.OGContext) error { return ctx.HTML_("edit.html") } -func DownloadZip(ctx *context.OGContext) error { +func DownloadZip(ctx *context.Context) error { gist := ctx.GetData("gist").(*db.Gist) revision := ctx.Param("revision") @@ -698,7 +698,7 @@ func DownloadZip(ctx *context.OGContext) error { return nil } -func Likes(ctx *context.OGContext) error { +func Likes(ctx *context.Context) error { gist := ctx.GetData("gist").(*db.Gist) pageInt := getPage(ctx) @@ -717,7 +717,7 @@ func Likes(ctx *context.OGContext) error { return ctx.HTML_("likes.html") } -func Forks(ctx *context.OGContext) error { +func Forks(ctx *context.Context) error { gist := ctx.GetData("gist").(*db.Gist) pageInt := getPage(ctx) @@ -741,7 +741,7 @@ func Forks(ctx *context.OGContext) error { return ctx.HTML_("forks.html") } -func Checkbox(ctx *context.OGContext) error { +func Checkbox(ctx *context.Context) error { filename := ctx.FormValue("file") checkboxNb := ctx.FormValue("checkbox") @@ -777,7 +777,7 @@ func Checkbox(ctx *context.OGContext) error { return ctx.PlainText(200, "ok") } -func Preview(ctx *context.OGContext) error { +func Preview(ctx *context.Context) error { content := ctx.FormValue("content") previewStr, err := render.MarkdownString(content) diff --git a/internal/web/handler/git_http.go b/internal/web/handlers/git_http.go similarity index 92% rename from internal/web/handler/git_http.go rename to internal/web/handlers/git_http.go index ee29f8a..06562a8 100644 --- a/internal/web/handler/git_http.go +++ b/internal/web/handlers/git_http.go @@ -1,4 +1,4 @@ -package handler +package handlers import ( "bytes" @@ -29,7 +29,7 @@ import ( var routes = []struct { gitUrl string method string - handler func(ctx *context.OGContext) error + handler func(ctx *context.Context) error }{ {"(.*?)/git-upload-pack$", "POST", uploadPack}, {"(.*?)/git-receive-pack$", "POST", receivePack}, @@ -44,7 +44,7 @@ var routes = []struct { {"(.*?)/objects/pack/pack-[0-9a-f]{40}\\.idx$", "GET", idxFile}, } -func GitHttp(ctx *context.OGContext) error { +func GitHttp(ctx *context.Context) error { for _, route := range routes { matched, _ := regexp.MatchString(route.gitUrl, ctx.Request().URL.Path) if ctx.Request().Method == route.method && matched { @@ -179,15 +179,15 @@ func GitHttp(ctx *context.OGContext) error { return ctx.NotFound("Gist not found") } -func uploadPack(ctx *context.OGContext) error { +func uploadPack(ctx *context.Context) error { return pack(ctx, "upload-pack") } -func receivePack(ctx *context.OGContext) error { +func receivePack(ctx *context.Context) error { return pack(ctx, "receive-pack") } -func pack(ctx *context.OGContext, serviceType string) error { +func pack(ctx *context.Context, serviceType string) error { noCacheHeaders(ctx) defer ctx.Request().Body.Close() @@ -226,7 +226,7 @@ func pack(ctx *context.OGContext, serviceType string) error { return nil } -func infoRefs(ctx *context.OGContext) error { +func infoRefs(ctx *context.Context) error { noCacheHeaders(ctx) var service string @@ -258,38 +258,38 @@ func infoRefs(ctx *context.OGContext) error { return nil } -func textFile(ctx *context.OGContext) error { +func textFile(ctx *context.Context) error { noCacheHeaders(ctx) return sendFile(ctx, "text/plain") } -func infoPacks(ctx *context.OGContext) error { +func infoPacks(ctx *context.Context) error { cacheHeadersForever(ctx) return sendFile(ctx, "text/plain; charset=utf-8") } -func looseObject(ctx *context.OGContext) error { +func looseObject(ctx *context.Context) error { cacheHeadersForever(ctx) return sendFile(ctx, "application/x-git-loose-object") } -func packFile(ctx *context.OGContext) error { +func packFile(ctx *context.Context) error { cacheHeadersForever(ctx) return sendFile(ctx, "application/x-git-packed-objects") } -func idxFile(ctx *context.OGContext) error { +func idxFile(ctx *context.Context) error { cacheHeadersForever(ctx) return sendFile(ctx, "application/x-git-packed-objects-toc") } -func noCacheHeaders(ctx *context.OGContext) { +func noCacheHeaders(ctx *context.Context) { ctx.Response().Header().Set("Expires", "Thu, 01 Jan 1970 00:00:00 UTC") ctx.Response().Header().Set("Pragma", "no-cache") ctx.Response().Header().Set("Cache-Control", "no-cache, max-age=0, must-revalidate") } -func cacheHeadersForever(ctx *context.OGContext) { +func cacheHeadersForever(ctx *context.Context) { now := time.Now().Unix() expires := now + 31536000 ctx.Response().Header().Set("Date", fmt.Sprintf("%d", now)) @@ -297,7 +297,7 @@ func cacheHeadersForever(ctx *context.OGContext) { ctx.Response().Header().Set("Cache-Control", "public, max-age=31536000") } -func basicAuth(ctx *context.OGContext) error { +func basicAuth(ctx *context.Context) error { ctx.Response().Header().Set("WWW-Authenticate", `Basic realm="."`) return ctx.PlainText(401, "Requires authentication") } @@ -312,7 +312,7 @@ func basicAuthDecode(encoded string) (string, string, error) { return auth[0], auth[1], nil } -func sendFile(ctx *context.OGContext, contentType string) error { +func sendFile(ctx *context.Context, contentType string) error { gitFile := "/" + strings.Join(strings.Split(ctx.Request().URL.Path, "/")[3:], "/") gitFile = path.Join(ctx.GetData("repositoryPath").(string), gitFile) fi, err := os.Stat(gitFile) diff --git a/internal/web/handler/healthcheck.go b/internal/web/handlers/healthcheck.go similarity index 83% rename from internal/web/handler/healthcheck.go rename to internal/web/handlers/healthcheck.go index 31c69c0..66bf4ee 100644 --- a/internal/web/handler/healthcheck.go +++ b/internal/web/handlers/healthcheck.go @@ -1,4 +1,4 @@ -package handler +package handlers import ( "github.com/thomiceli/opengist/internal/db" @@ -6,7 +6,7 @@ import ( "time" ) -func Healthcheck(ctx *context.OGContext) error { +func Healthcheck(ctx *context.Context) error { // Check database connection dbOk := "ok" httpStatus := 200 @@ -26,6 +26,6 @@ func Healthcheck(ctx *context.OGContext) error { // Metrics is a dummy handler to satisfy the /metrics endpoint (for Prometheus, Openmetrics, etc.) // until we have a proper metrics endpoint -func Metrics(ctx *context.OGContext) error { +func Metrics(ctx *context.Context) error { return ctx.String(200, "") } diff --git a/internal/web/handler/settings.go b/internal/web/handlers/settings.go similarity index 92% rename from internal/web/handler/settings.go rename to internal/web/handlers/settings.go index 03ad6a1..5788d81 100644 --- a/internal/web/handler/settings.go +++ b/internal/web/handlers/settings.go @@ -1,4 +1,4 @@ -package handler +package handlers import ( "crypto/md5" @@ -18,7 +18,7 @@ import ( "golang.org/x/crypto/ssh" ) -func UserSettings(ctx *context.OGContext) error { +func UserSettings(ctx *context.Context) error { user := ctx.User keys, err := db.GetSSHKeysByUserID(user.ID) @@ -46,7 +46,7 @@ func UserSettings(ctx *context.OGContext) error { return ctx.HTML_("settings.html") } -func EmailProcess(ctx *context.OGContext) error { +func EmailProcess(ctx *context.Context) error { user := ctx.User email := ctx.FormValue("email") var hash string @@ -69,7 +69,7 @@ func EmailProcess(ctx *context.OGContext) error { return ctx.RedirectTo("/settings") } -func AccountDeleteProcess(ctx *context.OGContext) error { +func AccountDeleteProcess(ctx *context.Context) error { user := ctx.User if err := user.Delete(); err != nil { @@ -79,7 +79,7 @@ func AccountDeleteProcess(ctx *context.OGContext) error { return ctx.RedirectTo("/all") } -func SshKeysProcess(ctx *context.OGContext) error { +func SshKeysProcess(ctx *context.Context) error { user := ctx.User dto := new(db.SSHKeyDTO) @@ -118,7 +118,7 @@ func SshKeysProcess(ctx *context.OGContext) error { return ctx.RedirectTo("/settings") } -func SshKeysDelete(ctx *context.OGContext) error { +func SshKeysDelete(ctx *context.Context) error { user := ctx.User keyId, err := strconv.Atoi(ctx.Param("id")) if err != nil { @@ -139,7 +139,7 @@ func SshKeysDelete(ctx *context.OGContext) error { return ctx.RedirectTo("/settings") } -func PasskeyDelete(ctx *context.OGContext) error { +func PasskeyDelete(ctx *context.Context) error { user := ctx.User keyId, err := strconv.Atoi(ctx.Param("id")) if err != nil { @@ -159,7 +159,7 @@ func PasskeyDelete(ctx *context.OGContext) error { return ctx.RedirectTo("/settings") } -func PasswordProcess(ctx *context.OGContext) error { +func PasswordProcess(ctx *context.Context) error { user := ctx.User dto := new(db.UserDTO) @@ -187,7 +187,7 @@ func PasswordProcess(ctx *context.OGContext) error { return ctx.RedirectTo("/settings") } -func UsernameProcess(ctx *context.OGContext) error { +func UsernameProcess(ctx *context.Context) error { user := ctx.User dto := new(db.UserDTO) diff --git a/internal/web/handler/util.go b/internal/web/handlers/util.go similarity index 87% rename from internal/web/handler/util.go rename to internal/web/handlers/util.go index 62ea6ad..3bde2ef 100644 --- a/internal/web/handler/util.go +++ b/internal/web/handlers/util.go @@ -1,4 +1,4 @@ -package handler +package handlers import ( "errors" @@ -8,7 +8,7 @@ import ( "strings" ) -func getPage(ctx *context.OGContext) int { +func getPage(ctx *context.Context) int { page := ctx.QueryParam("page") if page == "" { page = "1" @@ -22,7 +22,7 @@ func getPage(ctx *context.OGContext) int { return pageInt } -func paginate[T any](ctx *context.OGContext, data []*T, pageInt int, perPage int, templateDataName string, urlPage string, labels int, urlParams ...string) error { +func paginate[T any](ctx *context.Context, data []*T, pageInt int, perPage int, templateDataName string, urlPage string, labels int, urlParams ...string) error { lenData := len(data) if lenData == 0 && pageInt != 1 { return errors.New("page not found") diff --git a/internal/web/server/handler.go b/internal/web/server/handler.go index 60321aa..e4b3e60 100644 --- a/internal/web/server/handler.go +++ b/internal/web/server/handler.go @@ -5,30 +5,30 @@ import ( "github.com/thomiceli/opengist/internal/web/context" ) -type Handler func(ctx *context.OGContext) error +type Handler func(ctx *context.Context) error type Middleware func(next Handler) Handler -func (h Handler) ToEcho() echo.HandlerFunc { +func (h Handler) toEcho() echo.HandlerFunc { return func(c echo.Context) error { - return h(c.(*context.OGContext)) + return h(c.(*context.Context)) } } -func (m Middleware) ToEcho() echo.MiddlewareFunc { +func (m Middleware) toEcho() echo.MiddlewareFunc { return func(next echo.HandlerFunc) echo.HandlerFunc { - return m(func(c *context.OGContext) error { + return m(func(c *context.Context) error { return next(c) - }).ToEcho() + }).toEcho() } } func (h Handler) toEchoHandler() echo.HandlerFunc { return func(c echo.Context) error { - if ogc, ok := c.(*context.OGContext); ok { + if ogc, ok := c.(*context.Context); ok { return h(ogc) } // Could also add error handling for incorrect context type - return h(c.(*context.OGContext)) + return h(c.(*context.Context)) } } diff --git a/internal/web/server/middlewares.go b/internal/web/server/middlewares.go index 8620d53..d204606 100644 --- a/internal/web/server/middlewares.go +++ b/internal/web/server/middlewares.go @@ -11,7 +11,7 @@ import ( "github.com/thomiceli/opengist/internal/db" "github.com/thomiceli/opengist/internal/i18n" "github.com/thomiceli/opengist/internal/web/context" - "github.com/thomiceli/opengist/internal/web/handler" + "github.com/thomiceli/opengist/internal/web/handlers" "golang.org/x/text/cases" "golang.org/x/text/language" "html/template" @@ -31,8 +31,8 @@ func (s *Server) useCustomContext() { } func (s *Server) registerMiddlewares() { - s.echo.Use(Middleware(dataInit).ToEcho()) - s.echo.Use(Middleware(locale).ToEcho()) + s.echo.Use(Middleware(dataInit).toEcho()) + s.echo.Use(Middleware(locale).toEcho()) s.echo.Pre(middleware.MethodOverrideWithConfig(middleware.MethodOverrideConfig{ Getter: middleware.MethodFromForm("_method"), @@ -50,8 +50,7 @@ func (s *Server) registerMiddlewares() { })) s.echo.Use(middleware.Recover()) s.echo.Use(middleware.Secure()) - - s.echo.Use(Middleware(sessionInit).ToEcho()) + s.echo.Use(Middleware(sessionInit).toEcho()) if !s.ignoreCsrf { s.echo.Use(middleware.CSRFWithConfig(middleware.CSRFConfig{ @@ -60,7 +59,7 @@ func (s *Server) registerMiddlewares() { CookieHTTPOnly: true, CookieSameSite: http.SameSiteStrictMode, })) - s.echo.Use(Middleware(csrfInit).ToEcho()) + s.echo.Use(Middleware(csrfInit).toEcho()) } } @@ -87,7 +86,7 @@ func (s *Server) errorHandler(err error, ctx echo.Context) { } func dataInit(next Handler) Handler { - return func(ctx *context.OGContext) error { + return func(ctx *context.Context) error { ctx.SetData("loadStartTime", time.Now()) if err := loadSettings(ctx); err != nil { @@ -122,7 +121,7 @@ func dataInit(next Handler) Handler { } func writePermission(next Handler) Handler { - return func(ctx *context.OGContext) error { + return func(ctx *context.Context) error { gist := ctx.GetData("gist") user := ctx.User if !gist.(*db.Gist).CanWrite(user) { @@ -133,7 +132,7 @@ func writePermission(next Handler) Handler { } func adminPermission(next Handler) Handler { - return func(ctx *context.OGContext) error { + return func(ctx *context.Context) error { user := ctx.User if user == nil || !user.IsAdmin { return ctx.NotFound("User not found") @@ -143,7 +142,7 @@ func adminPermission(next Handler) Handler { } func logged(next Handler) Handler { - return func(ctx *context.OGContext) error { + return func(ctx *context.Context) error { user := ctx.User if user != nil { return next(ctx) @@ -153,7 +152,7 @@ func logged(next Handler) Handler { } func inMFASession(next Handler) Handler { - return func(ctx *context.OGContext) error { + return func(ctx *context.Context) error { sess := ctx.GetSession() _, ok := sess.Values["mfaID"].(uint) if !ok { @@ -165,12 +164,12 @@ func inMFASession(next Handler) Handler { func makeCheckRequireLogin(isSingleGistAccess bool) Middleware { return func(next Handler) Handler { - return func(ctx *context.OGContext) error { + return func(ctx *context.Context) error { if user := ctx.User; user != nil { return next(ctx) } - allow, err := auth.ShouldAllowUnauthenticatedGistAccess(handler.ContextAuthInfo{Context: ctx}, isSingleGistAccess) + allow, err := auth.ShouldAllowUnauthenticatedGistAccess(handlers.ContextAuthInfo{Context: ctx}, isSingleGistAccess) if err != nil { log.Fatal().Err(err).Msg("Failed to check if unauthenticated access is allowed") } @@ -188,12 +187,12 @@ func checkRequireLogin(next Handler) Handler { return makeCheckRequireLogin(false)(next) } -func noRouteFound(ctx *context.OGContext) error { +func noRouteFound(ctx *context.Context) error { return ctx.NotFound("Page not found") } func locale(next Handler) Handler { - return func(ctx *context.OGContext) error { + return func(ctx *context.Context) error { // Check URL arguments lang := ctx.Request().URL.Query().Get("lang") changeLang := lang != "" @@ -236,7 +235,7 @@ func locale(next Handler) Handler { } func sessionInit(next Handler) Handler { - return func(ctx *context.OGContext) error { + return func(ctx *context.Context) error { sess := ctx.GetSession() if sess.Values["user"] != nil { var err error @@ -263,7 +262,7 @@ func sessionInit(next Handler) Handler { } func csrfInit(next Handler) Handler { - return func(ctx *context.OGContext) error { + return func(ctx *context.Context) error { var csrf string if csrfToken, ok := ctx.Get("csrf").(string); ok { csrf = csrfToken @@ -275,7 +274,7 @@ func csrfInit(next Handler) Handler { } } -func loadSettings(ctx *context.OGContext) error { +func loadSettings(ctx *context.Context) error { settings, err := db.GetSettings() if err != nil { return err @@ -289,8 +288,8 @@ func loadSettings(ctx *context.OGContext) error { return nil } -func GistInit(next Handler) Handler { - return func(ctx *context.OGContext) error { +func gistInit(next Handler) Handler { + return func(ctx *context.Context) error { currUser := ctx.User userName := ctx.Param("user") @@ -369,10 +368,10 @@ func GistInit(next Handler) Handler { } } -// GistSoftInit try to load a gist (same as gistInit) but does not return a 404 if the gist is not found +// gistSoftInit try to load a gist (same as gistInit) but does not return a 404 if the gist is not found // useful for git clients using HTTP to obfuscate the existence of a private gist -func GistSoftInit(next Handler) Handler { - return func(ctx *context.OGContext) error { +func gistSoftInit(next Handler) Handler { + return func(ctx *context.Context) error { userName := ctx.Param("user") gistName := ctx.Param("gistname") @@ -385,9 +384,9 @@ func GistSoftInit(next Handler) Handler { } } -// GistNewPushSoftInit has the same behavior as gistSoftInit but create a new gist empty instead -func GistNewPushSoftInit(next Handler) Handler { - return func(ctx *context.OGContext) error { +// gistNewPushSoftInit has the same behavior as gistSoftInit but create a new gist empty instead +func gistNewPushSoftInit(next Handler) Handler { + return func(ctx *context.Context) error { ctx.SetData("gist", new(db.Gist)) return next(ctx) } diff --git a/internal/web/server/renderer.go b/internal/web/server/renderer.go index 51a2d0c..ef34890 100644 --- a/internal/web/server/renderer.go +++ b/internal/web/server/renderer.go @@ -11,7 +11,7 @@ import ( "github.com/thomiceli/opengist/internal/git" "github.com/thomiceli/opengist/internal/index" "github.com/thomiceli/opengist/internal/web/context" - "github.com/thomiceli/opengist/internal/web/handler" + "github.com/thomiceli/opengist/internal/web/handlers" "github.com/thomiceli/opengist/public" "github.com/thomiceli/opengist/templates" htmlpkg "html" @@ -158,7 +158,7 @@ func (s *Server) setFuncMap() { return dict, nil }, "addMetadataToSearchQuery": func(input, key, value string) string { - content, metadata := handler.ParseSearchQueryStr(input) + content, metadata := handlers.ParseSearchQueryStr(input) metadata[key] = value diff --git a/internal/web/server/router.go b/internal/web/server/router.go index f963c07..445a353 100644 --- a/internal/web/server/router.go +++ b/internal/web/server/router.go @@ -5,7 +5,7 @@ import ( "github.com/thomiceli/opengist/internal/config" "github.com/thomiceli/opengist/internal/index" "github.com/thomiceli/opengist/internal/web/context" - "github.com/thomiceli/opengist/internal/web/handler" + "github.com/thomiceli/opengist/internal/web/handlers" "github.com/thomiceli/opengist/public" "net/http" "os" @@ -19,107 +19,107 @@ func (s *Server) registerRoutes() { r := NewRouter(s.echo.Group("")) { - r.GET("/", handler.Create, logged) - r.POST("/", handler.ProcessCreate, logged) - r.POST("/preview", handler.Preview, logged) + r.GET("/", handlers.Create, logged) + r.POST("/", handlers.ProcessCreate, logged) + r.POST("/preview", handlers.Preview, logged) - r.GET("/healthcheck", handler.Healthcheck) - r.GET("/metrics", handler.Metrics) + r.GET("/healthcheck", handlers.Healthcheck) + r.GET("/metrics", handlers.Metrics) - r.GET("/register", handler.Register) - r.POST("/register", handler.ProcessRegister) - r.GET("/login", handler.Login) - r.POST("/login", handler.ProcessLogin) - r.GET("/logout", handler.Logout) - r.GET("/oauth/:provider", handler.Oauth) - r.GET("/oauth/:provider/callback", handler.OauthCallback) - r.GET("/oauth/:provider/unlink", handler.OauthUnlink, logged) - r.POST("/webauthn/bind", handler.BeginWebAuthnBinding, logged) - r.POST("/webauthn/bind/finish", handler.FinishWebAuthnBinding, logged) - r.POST("/webauthn/login", handler.BeginWebAuthnLogin) - r.POST("/webauthn/login/finish", handler.FinishWebAuthnLogin) - r.POST("/webauthn/assertion", handler.BeginWebAuthnAssertion, inMFASession) - r.POST("/webauthn/assertion/finish", handler.FinishWebAuthnAssertion, inMFASession) - r.GET("/mfa", handler.Mfa, inMFASession) - r.POST("/mfa/totp/assertion", handler.AssertTotp, inMFASession) + r.GET("/register", handlers.Register) + r.POST("/register", handlers.ProcessRegister) + r.GET("/login", handlers.Login) + r.POST("/login", handlers.ProcessLogin) + r.GET("/logout", handlers.Logout) + r.GET("/oauth/:provider", handlers.Oauth) + r.GET("/oauth/:provider/callback", handlers.OauthCallback) + r.GET("/oauth/:provider/unlink", handlers.OauthUnlink, logged) + r.POST("/webauthn/bind", handlers.BeginWebAuthnBinding, logged) + r.POST("/webauthn/bind/finish", handlers.FinishWebAuthnBinding, logged) + r.POST("/webauthn/login", handlers.BeginWebAuthnLogin) + r.POST("/webauthn/login/finish", handlers.FinishWebAuthnLogin) + r.POST("/webauthn/assertion", handlers.BeginWebAuthnAssertion, inMFASession) + r.POST("/webauthn/assertion/finish", handlers.FinishWebAuthnAssertion, inMFASession) + r.GET("/mfa", handlers.Mfa, inMFASession) + r.POST("/mfa/totp/assertion", handlers.AssertTotp, inMFASession) sA := r.SubGroup("/settings") { sA.Use(logged) - sA.GET("", handler.UserSettings) - sA.POST("/email", handler.EmailProcess) - sA.DELETE("/account", handler.AccountDeleteProcess) - sA.POST("/ssh-keys", handler.SshKeysProcess) - sA.DELETE("/ssh-keys/:id", handler.SshKeysDelete) - sA.DELETE("/passkeys/:id", handler.PasskeyDelete) - sA.PUT("/password", handler.PasswordProcess) - sA.PUT("/username", handler.UsernameProcess) - sA.GET("/totp/generate", handler.BeginTotp) - sA.POST("/totp/generate", handler.FinishTotp) - sA.DELETE("/totp", handler.DisableTotp) - sA.POST("/totp/regenerate", handler.RegenerateTotpRecoveryCodes) + sA.GET("", handlers.UserSettings) + sA.POST("/email", handlers.EmailProcess) + sA.DELETE("/account", handlers.AccountDeleteProcess) + sA.POST("/ssh-keys", handlers.SshKeysProcess) + sA.DELETE("/ssh-keys/:id", handlers.SshKeysDelete) + sA.DELETE("/passkeys/:id", handlers.PasskeyDelete) + sA.PUT("/password", handlers.PasswordProcess) + sA.PUT("/username", handlers.UsernameProcess) + sA.GET("/totp/generate", handlers.BeginTotp) + sA.POST("/totp/generate", handlers.FinishTotp) + sA.DELETE("/totp", handlers.DisableTotp) + sA.POST("/totp/regenerate", handlers.RegenerateTotpRecoveryCodes) } sB := r.SubGroup("/admin-panel") { sB.Use(adminPermission) - sB.GET("", handler.AdminIndex) - sB.GET("/users", handler.AdminUsers) - sB.POST("/users/:user/delete", handler.AdminUserDelete) - sB.GET("/gists", handler.AdminGists) - sB.POST("/gists/:gist/delete", handler.AdminGistDelete) - sB.GET("/invitations", handler.AdminInvitations) - sB.POST("/invitations", handler.AdminInvitationsCreate) - sB.POST("/invitations/:id/delete", handler.AdminInvitationsDelete) - sB.POST("/sync-fs", handler.AdminSyncReposFromFS) - sB.POST("/sync-db", handler.AdminSyncReposFromDB) - sB.POST("/gc-repos", handler.AdminGcRepos) - sB.POST("/sync-previews", handler.AdminSyncGistPreviews) - sB.POST("/reset-hooks", handler.AdminResetHooks) - sB.POST("/index-gists", handler.AdminIndexGists) - sB.GET("/configuration", handler.AdminConfig) - sB.PUT("/set-config", handler.AdminSetConfig) + sB.GET("", handlers.AdminIndex) + sB.GET("/users", handlers.AdminUsers) + sB.POST("/users/:user/delete", handlers.AdminUserDelete) + sB.GET("/gists", handlers.AdminGists) + sB.POST("/gists/:gist/delete", handlers.AdminGistDelete) + sB.GET("/invitations", handlers.AdminInvitations) + sB.POST("/invitations", handlers.AdminInvitationsCreate) + sB.POST("/invitations/:id/delete", handlers.AdminInvitationsDelete) + sB.POST("/sync-fs", handlers.AdminSyncReposFromFS) + sB.POST("/sync-db", handlers.AdminSyncReposFromDB) + sB.POST("/gc-repos", handlers.AdminGcRepos) + sB.POST("/sync-previews", handlers.AdminSyncGistPreviews) + sB.POST("/reset-hooks", handlers.AdminResetHooks) + sB.POST("/index-gists", handlers.AdminIndexGists) + sB.GET("/configuration", handlers.AdminConfig) + sB.PUT("/set-config", handlers.AdminSetConfig) } if config.C.HttpGit { - r.Any("/init/*", handler.GitHttp, GistNewPushSoftInit) + r.Any("/init/*", handlers.GitHttp, gistNewPushSoftInit) } - r.GET("/all", handler.AllGists, checkRequireLogin) + r.GET("/all", handlers.AllGists, checkRequireLogin) if index.Enabled() { - r.GET("/search", handler.Search, checkRequireLogin) + r.GET("/search", handlers.Search, checkRequireLogin) } else { - r.GET("/search", handler.AllGists, checkRequireLogin) + r.GET("/search", handlers.AllGists, checkRequireLogin) } - r.GET("/:user", handler.AllGists, checkRequireLogin) - r.GET("/:user/liked", handler.AllGists, checkRequireLogin) - r.GET("/:user/forked", handler.AllGists, checkRequireLogin) + r.GET("/:user", handlers.AllGists, checkRequireLogin) + r.GET("/:user/liked", handlers.AllGists, checkRequireLogin) + r.GET("/:user/forked", handlers.AllGists, checkRequireLogin) sC := r.SubGroup("/:user/:gistname") { - sC.Use(makeCheckRequireLogin(true), GistInit) - sC.GET("", handler.GistIndex) - sC.GET("/rev/:revision", handler.GistIndex) - sC.GET("/revisions", handler.Revisions) - sC.GET("/archive/:revision", handler.DownloadZip) - sC.POST("/visibility", handler.EditVisibility, logged, writePermission) - sC.POST("/delete", handler.DeleteGist, logged, writePermission) - sC.GET("/raw/:revision/:file", handler.RawFile) - sC.GET("/download/:revision/:file", handler.DownloadFile) - sC.GET("/edit", handler.Edit, logged, writePermission) - sC.POST("/edit", handler.ProcessCreate, logged, writePermission) - sC.POST("/like", handler.Like, logged) - sC.GET("/likes", handler.Likes, checkRequireLogin) - sC.POST("/fork", handler.Fork, logged) - sC.GET("/forks", handler.Forks, checkRequireLogin) - sC.PUT("/checkbox", handler.Checkbox, logged, writePermission) + sC.Use(makeCheckRequireLogin(true), gistInit) + sC.GET("", handlers.GistIndex) + sC.GET("/rev/:revision", handlers.GistIndex) + sC.GET("/revisions", handlers.Revisions) + sC.GET("/archive/:revision", handlers.DownloadZip) + sC.POST("/visibility", handlers.EditVisibility, logged, writePermission) + sC.POST("/delete", handlers.DeleteGist, logged, writePermission) + sC.GET("/raw/:revision/:file", handlers.RawFile) + sC.GET("/download/:revision/:file", handlers.DownloadFile) + sC.GET("/edit", handlers.Edit, logged, writePermission) + sC.POST("/edit", handlers.ProcessCreate, logged, writePermission) + sC.POST("/like", handlers.Like, logged) + sC.GET("/likes", handlers.Likes, checkRequireLogin) + sC.POST("/fork", handlers.Fork, logged) + sC.GET("/forks", handlers.Forks, checkRequireLogin) + sC.PUT("/checkbox", handlers.Checkbox, logged, writePermission) } } customFs := os.DirFS(filepath.Join(config.GetHomeDir(), "custom")) - r.GET("/assets/*", func(ctx *context.OGContext) error { + r.GET("/assets/*", func(ctx *context.Context) error { if _, err := public.Files.Open(path.Join("assets", ctx.Param("*"))); !s.dev && err == nil { ctx.Response().Header().Set("Cache-Control", "public, max-age=31536000") ctx.Response().Header().Set("Expires", time.Now().AddDate(1, 0, 0).Format(http.TimeFormat)) @@ -140,7 +140,7 @@ func (s *Server) registerRoutes() { // Git HTTP routes if config.C.HttpGit { - r.Any("/:user/:gistname/*", handler.GitHttp, GistSoftInit) + r.Any("/:user/:gistname/*", handlers.GitHttp, gistSoftInit) } r.Any("/*", noRouteFound) @@ -151,19 +151,16 @@ type Router struct { *echo.Group } -// NewRouter creates a new Router instance func NewRouter(g *echo.Group) *Router { return &Router{Group: g} } -// SubGroup returns a new Router group with the given prefix and middleware func (r *Router) SubGroup(prefix string, m ...Middleware) *Router { - // Convert middleware only when creating group echoMiddleware := make([]echo.MiddlewareFunc, len(m)) for i, mw := range m { mw := mw // capture for closure echoMiddleware[i] = func(next echo.HandlerFunc) echo.HandlerFunc { - return chain(func(c *context.OGContext) error { + return chain(func(c *context.Context) error { return next(c) }, mw).toEchoHandler() } @@ -199,7 +196,7 @@ func (r *Router) Use(middleware ...Middleware) { for _, m := range middleware { m := m // capture for closure r.Group.Use(func(next echo.HandlerFunc) echo.HandlerFunc { - return chain(func(c *context.OGContext) error { + return chain(func(c *context.Context) error { return next(c) }, m).toEchoHandler() }) diff --git a/internal/web/server/server.go b/internal/web/server/server.go index 8019adf..cda0b42 100644 --- a/internal/web/server/server.go +++ b/internal/web/server/server.go @@ -1,10 +1,8 @@ package server import ( - "errors" "github.com/thomiceli/opengist/internal/utils" "net/http" - "strings" "github.com/gorilla/sessions" "github.com/labstack/echo/v4" @@ -27,6 +25,7 @@ func NewServer(isDev bool, sessionsPath string, ignoreCsrf bool) *Server { e := echo.New() e.HideBanner = true e.HidePort = true + e.Validator = utils.NewValidator() s := &Server{echo: e, dev: isDev, sessionsPath: sessionsPath, ignoreCsrf: ignoreCsrf} @@ -40,8 +39,6 @@ func NewServer(isDev bool, sessionsPath string, ignoreCsrf bool) *Server { s.setFuncMap() s.echo.HTTPErrorHandler = s.errorHandler - e.Validator = utils.NewValidator() - if !s.dev { s.parseManifestEntries() }