mirror of
https://github.com/thomiceli/opengist.git
synced 2025-01-09 18:02:40 +00:00
wip
This commit is contained in:
parent
68c6f26385
commit
e589d3d727
13 changed files with 227 additions and 234 deletions
|
@ -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...)
|
||||
}
|
||||
|
|
|
@ -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 {
|
|
@ -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) {
|
|
@ -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)
|
|
@ -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)
|
|
@ -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, "")
|
||||
}
|
|
@ -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)
|
|
@ -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")
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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()
|
||||
})
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue