newsbox/actions/app.go
Adriano Caloiaro 8ae801ae5f
Initial commit
2023-02-15 08:57:48 -08:00

178 lines
4.7 KiB
Go

package actions
import (
"fmt"
"net/http"
"newsbox/internal"
"newsbox/locales"
"newsbox/models"
"newsbox/public"
"github.com/gobuffalo/buffalo"
"github.com/gobuffalo/buffalo-pop/v3/pop/popmw"
"github.com/gobuffalo/envy"
csrf "github.com/gobuffalo/mw-csrf"
i18n "github.com/gobuffalo/mw-i18n/v2"
paramlogger "github.com/gobuffalo/mw-paramlogger"
"github.com/gobuffalo/pop/v6"
"github.com/gofrs/uuid"
"github.com/markbates/goth/gothic"
)
// ENV is used to help switch settings based on where the
// application is being run. Default is "development".
var ENV = envy.Get("GO_ENV", "development")
var (
app *buffalo.App
T *i18n.Translator
)
func App() *buffalo.App {
if app == nil {
app = buffalo.New(buffalo.Options{
Env: ENV,
SessionName: "_newsbox_session",
})
// Log request parameters (filters apply).
app.Use(paramlogger.ParameterLogger)
// Protect against CSRF attacks. https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)
// Remove to disable this.
cs := csrf.New
app.Use(cs)
// Wraps each request in a transaction.
// c.Value("tx").(*pop.Connection)
// Remove to disable this.
app.Use(popmw.Transaction(models.DB))
// Setup and use translations:
app.Use(translations())
// Inject site-side template variables to be used in template
app.Use(InjectSiteTemplateVariables)
// Inject critical flash messages
app.Use(InjectFlashMessages)
// Inject a "tx" into th context for every request
app.Use(popmw.Transaction(models.DB))
// Set the current user and require authorization
app.Use(SetCurrentUser)
app.Use(Authorize)
app.GET("/", HomeHandler)
// Authentication
auth := app.Group("/login")
auth.GET("/", LoginIndex)
auth.POST("/", AuthUser)
auth.Middleware.Skip(Authorize, LoginIndex, AuthUser)
// Logout
app.GET("/logout", AuthLogout)
// Oauth
oauth := app.Group("/oauth")
app.Middleware.Skip(Authorize, HomeHandler)
bah := buffalo.WrapHandlerFunc(gothic.BeginAuthHandler)
oauth.Middleware.Skip(Authorize, bah, OauthCallback)
oauth.GET("{provider}", bah)
oauth.GET("{provider}/callback", OauthCallback)
oauth.DELETE("", AuthLogout)
// User Registration
users := app.Group("/users")
users.GET("/new", UsersNew)
users.POST("/", UsersCreate)
users.Middleware.Remove(Authorize)
// Email verification
email_verification := app.Group("/users/email_verification")
email_verification.GET("/{email_verification_id}", UserEmailVerificationHandler)
email_verification.Middleware.Remove(Authorize)
// Webhooks
webhooks := app.Group("/webhooks")
webhooks.Middleware.Remove(cs)
webhooks.POST("/mailgun", MailgunWebhook)
webhooks.Middleware.Remove(Authorize)
// Legal
legal := app.Group("/legal")
legal.GET("/tos", TOSHandler)
legal.Middleware.Remove(Authorize)
// Profile
profile := app.Group("/profile")
profile.GET("/", ShowProfile)
profile.GET("/edit", EditProfile)
profile.POST("/update", UpdateProfile)
profile.POST("/changepassword", UpdatePassword)
// Messages
app.Resource("/messages", MessagesResource{})
messages := app.Group("/messages")
messages.GET("/{message_id}/content", MessagesResource{}.ShowContent)
app.ServeFiles("/", http.FS(public.FS())) // serve files from the public directory
}
return app
}
// translations will load locale files, set up the translator `actions.T`,
// and will return a middleware to use to load the correct locale for each
// request.
// for more information: https://gobuffalo.io/en/docs/localization
func translations() buffalo.MiddlewareFunc {
var err error
if T, err = i18n.New(locales.FS(), "en-US"); err != nil {
app.Stop(err)
}
return T.Middleware()
}
func InjectSiteTemplateVariables(next buffalo.Handler) buffalo.Handler {
return func(c buffalo.Context) error {
c.Set("site_domain", internal.SiteDomain())
c.Set("site_name", internal.SiteName())
c.Set("analytics_enabled", internal.AnalyticsEnabled())
c.Set("analytics_enabled_self_hosting", internal.AnalyticsSelfHostingEnabled())
c.Set("payments_enabled", internal.PaymentsEnabled())
err := next(c)
return err
}
}
func InjectFlashMessages(next buffalo.Handler) buffalo.Handler {
return func(c buffalo.Context) error {
if uid := c.Session().Get("current_user_id"); uid != nil {
tx := c.Value("tx").(*pop.Connection)
u := &models.User{}
err := tx.EagerPreload().Find(u, uid)
if err != nil {
return err
}
if u.Email.Interface() == "" {
c.Flash().Add("action_required", "Edit your profile and add an email address.")
} else if u.EmailVerification.ID != uuid.Nil {
c.Flash().Add("action_required", fmt.Sprintf("Account is pending email verification of: %s", u.Email.Interface()))
} else {
c.Flash().Delete("action_required")
}
}
err := next(c)
return err
}
}