Skip to content

Commit

Permalink
Use middleware for auth, added spam warning in recovery page
Browse files Browse the repository at this point in the history
  • Loading branch information
svera authored Mar 8, 2024
1 parent db4d450 commit f30fa5b
Show file tree
Hide file tree
Showing 25 changed files with 272 additions and 278 deletions.
117 changes: 8 additions & 109 deletions internal/webserver/controller.go
Original file line number Diff line number Diff line change
@@ -1,34 +1,22 @@
package webserver

import (
"errors"
"fmt"
"log"

"github.com/gofiber/fiber/v2"
jwtware "github.com/gofiber/jwt/v3"
"github.com/spf13/afero"
"github.com/svera/coreander/v3/internal/index"
"github.com/svera/coreander/v3/internal/metadata"
"github.com/svera/coreander/v3/internal/webserver/controller/auth"
"github.com/svera/coreander/v3/internal/webserver/controller/document"
"github.com/svera/coreander/v3/internal/webserver/controller/highlight"
"github.com/svera/coreander/v3/internal/webserver/controller/user"
"github.com/svera/coreander/v3/internal/webserver/infrastructure"
"github.com/svera/coreander/v3/internal/webserver/jwtclaimsreader"
"github.com/svera/coreander/v3/internal/webserver/model"
"gorm.io/gorm"
)

type Controllers struct {
Auth *auth.Controller
Users *user.Controller
Highlights *highlight.Controller
Documents *document.Controller
AllowIfNotLoggedInMiddleware func(c *fiber.Ctx) error
AlwaysRequireAuthenticationMiddleware func(c *fiber.Ctx) error
ConfigurableAuthenticationMiddleware func(c *fiber.Ctx) error
ErrorHandler func(c *fiber.Ctx, err error) error
Auth *auth.Controller
Users *user.Controller
Highlights *highlight.Controller
Documents *document.Controller
}

func SetupControllers(cfg Config, db *gorm.DB, metadataReaders map[string]metadata.Reader, idx *index.BleveIndexer, sender Sender, appFs afero.Fs) Controllers {
Expand Down Expand Up @@ -58,99 +46,10 @@ func SetupControllers(cfg Config, db *gorm.DB, metadataReaders map[string]metada
UploadDocumentMaxSize: cfg.UploadDocumentMaxSize,
}

authController := auth.NewController(usersRepository, sender, authCfg, printers)
usersController := user.NewController(usersRepository, usersCfg)
highlightsController := highlight.NewController(highlightsRepository, usersRepository, sender, cfg.WordsPerMinute, idx)
documentsController := document.NewController(highlightsRepository, sender, idx, metadataReaders, appFs, documentsCfg)

emailSendingConfigured := true
if _, ok := sender.(*infrastructure.NoEmail); ok {
emailSendingConfigured = false
}

supportedLanguages := getSupportedLanguages()

forbidden := func(c *fiber.Ctx) error {
return c.Status(fiber.StatusForbidden).Render("auth/login", fiber.Map{
"Lang": chooseBestLanguage(c, supportedLanguages),
"Title": "Login",
"Version": c.App().Config().AppName,
"EmailSendingConfigured": emailSendingConfigured,
"SupportedLanguages": supportedLanguages,
}, "layout")
}

return Controllers{
Auth: authController,
Users: usersController,
Highlights: highlightsController,
Documents: documentsController,
AllowIfNotLoggedInMiddleware: jwtware.New(jwtware.Config{
SigningKey: cfg.JwtSecret,
SigningMethod: "HS256",
TokenLookup: "cookie:coreander",
SuccessHandler: func(c *fiber.Ctx) error {
return fiber.ErrForbidden
},
ErrorHandler: func(c *fiber.Ctx, err error) error {
return c.Next()
},
}),
AlwaysRequireAuthenticationMiddleware: jwtware.New(jwtware.Config{
SigningKey: cfg.JwtSecret,
SigningMethod: "HS256",
TokenLookup: "cookie:coreander",
SuccessHandler: func(c *fiber.Ctx) error {
c.Locals("Session", jwtclaimsreader.SessionData(c))
return c.Next()
},
ErrorHandler: func(c *fiber.Ctx, err error) error {
return forbidden(c)
},
}),
ConfigurableAuthenticationMiddleware: jwtware.New(jwtware.Config{
SigningKey: cfg.JwtSecret,
SigningMethod: "HS256",
TokenLookup: "cookie:coreander",
SuccessHandler: func(c *fiber.Ctx) error {
c.Locals("Session", jwtclaimsreader.SessionData(c))
return c.Next()
},
ErrorHandler: func(c *fiber.Ctx, err error) error {
err = c.Next()
if cfg.RequireAuth {
return forbidden(c)
}
return err
},
}),
ErrorHandler: func(c *fiber.Ctx, err error) error {
// Status code defaults to 500
code := fiber.StatusInternalServerError
// Retrieve the custom status code if it's a *fiber.Error
var e *fiber.Error
if errors.As(err, &e) {
code = e.Code
}

// Send custom error page
err = c.Status(code).Render(
fmt.Sprintf("errors/%d", code),
fiber.Map{
"Lang": chooseBestLanguage(c, supportedLanguages),
"Title": "Coreander",
"Session": jwtclaimsreader.SessionData(c),
"Version": c.App().Config().AppName,
},
"layout")

if err != nil {
log.Println(err)
// In case the Render fails
return c.Status(fiber.StatusInternalServerError).SendString("Internal Server Error")
}

return nil
},
Auth: auth.NewController(usersRepository, sender, authCfg, printers),
Users: user.NewController(usersRepository, usersCfg),
Highlights: highlight.NewController(highlightsRepository, usersRepository, sender, cfg.WordsPerMinute, idx),
Documents: document.NewController(highlightsRepository, sender, idx, metadataReaders, appFs, documentsCfg),
}
}
2 changes: 1 addition & 1 deletion internal/webserver/controller/auth/edit-password.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package auth
import "github.com/gofiber/fiber/v2"

func (a *Controller) EditPassword(c *fiber.Ctx) error {
if _, err := a.validateRecoveryAccess(c, c.Query("id")); err != nil {
if _, err := a.validateRecoveryAccess(c.Query("id")); err != nil {
return err
}

Expand Down
7 changes: 2 additions & 5 deletions internal/webserver/controller/auth/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,13 @@ import (
"strings"

"github.com/gofiber/fiber/v2"
"github.com/svera/coreander/v3/internal/webserver/controller"
"github.com/svera/coreander/v3/internal/webserver/infrastructure"
)

func (a *Controller) Login(c *fiber.Ctx) error {
resetPassword := fmt.Sprintf(
"%s://%s%s/%s/reset-password",
c.Protocol(),
a.config.Hostname,
controller.UrlPort(c.Protocol(), a.config.Port),
"%s/%s/reset-password",
c.Locals("fqdn").(string),
c.Params("lang"),
)

Expand Down
7 changes: 2 additions & 5 deletions internal/webserver/controller/auth/request.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (

"github.com/gofiber/fiber/v2"
"github.com/google/uuid"
"github.com/svera/coreander/v3/internal/webserver/controller"
"github.com/svera/coreander/v3/internal/webserver/infrastructure"
)

Expand All @@ -31,10 +30,8 @@ func (a *Controller) Request(c *fiber.Ctx) error {
}

recoveryLink := fmt.Sprintf(
"%s://%s%s/%s/reset-password?id=%s",
c.Protocol(),
a.config.Hostname,
controller.UrlPort(c.Protocol(), a.config.Port),
"%s/%s/reset-password?id=%s",
c.Locals("fqdn"),
c.Params("lang"),
user.RecoveryUUID,
)
Expand Down
4 changes: 2 additions & 2 deletions internal/webserver/controller/auth/update-password.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
)

func (a *Controller) UpdatePassword(c *fiber.Ctx) error {
user, err := a.validateRecoveryAccess(c, c.FormValue("id"))
user, err := a.validateRecoveryAccess(c.FormValue("id"))
if err != nil {
return err
}
Expand All @@ -36,7 +36,7 @@ func (a *Controller) UpdatePassword(c *fiber.Ctx) error {
return c.Redirect(fmt.Sprintf("/%s/login", c.Params("lang")))
}

func (a *Controller) validateRecoveryAccess(c *fiber.Ctx, recoveryUuid string) (*model.User, error) {
func (a *Controller) validateRecoveryAccess(recoveryUuid string) (*model.User, error) {
if _, ok := a.sender.(*infrastructure.NoEmail); ok {
return &model.User{}, fiber.ErrNotFound
}
Expand Down
17 changes: 0 additions & 17 deletions internal/webserver/controller/controller.go

This file was deleted.

8 changes: 0 additions & 8 deletions internal/webserver/controller/document/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,9 @@ import (
"path/filepath"

"github.com/gofiber/fiber/v2"
"github.com/svera/coreander/v3/internal/webserver/jwtclaimsreader"
"github.com/svera/coreander/v3/internal/webserver/model"
)

func (d *Controller) Delete(c *fiber.Ctx) error {
session := jwtclaimsreader.SessionData(c)

if session.Role != model.RoleAdmin {
return fiber.ErrForbidden
}

if c.FormValue("slug") == "" {
return fiber.ErrBadRequest
}
Expand Down
30 changes: 2 additions & 28 deletions internal/webserver/controller/document/upload.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,34 +9,14 @@ import (
"os"
"path/filepath"
"slices"
"strings"

"github.com/gofiber/fiber/v2"
"github.com/svera/coreander/v3/internal/webserver/controller"
"github.com/svera/coreander/v3/internal/webserver/model"
"github.com/valyala/fasthttp"
)

func (d *Controller) UploadForm(c *fiber.Ctx) error {
var session model.User
if val, ok := c.Locals("Session").(model.User); ok {
session = val
}

if session.Role != model.RoleAdmin {
return fiber.ErrForbidden
}

upload := fmt.Sprintf(
"%s://%s%s/%s/upload",
c.Protocol(),
d.config.Hostname,
controller.UrlPort(c.Protocol(), d.config.Port),
c.Params("lang"),
)

msg := ""
if ref := string(c.Request().Header.Referer()); strings.HasPrefix(ref, upload) {
if c.Params("success") != "" {
msg = "Document uploaded successfully."
}

Expand All @@ -48,12 +28,6 @@ func (d *Controller) UploadForm(c *fiber.Ctx) error {
}

func (d *Controller) Upload(c *fiber.Ctx) error {
session := c.Locals("Session").(model.User)

if session.Role != model.RoleAdmin {
return fiber.ErrForbidden
}

file, err := c.FormFile("filename")
if err != nil {
if errors.Is(err, fasthttp.ErrMissingFile) {
Expand Down Expand Up @@ -105,7 +79,7 @@ func (d *Controller) Upload(c *fiber.Ctx) error {
return internalServerErrorStatus
}

return c.Redirect(fmt.Sprintf("/%s/upload", c.Params("lang")))
return c.Redirect(fmt.Sprintf("/%s/upload?success=1", c.Params("lang")))
}

func fileToBytes(fileHeader *multipart.FileHeader) ([]byte, error) {
Expand Down
23 changes: 0 additions & 23 deletions internal/webserver/controller/user/controller.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package user

import (
"github.com/gofiber/fiber/v2"
"github.com/svera/coreander/v3/internal/result"
"github.com/svera/coreander/v3/internal/webserver/model"
)
Expand Down Expand Up @@ -34,25 +33,3 @@ func NewController(repository usersRepository, usersCfg Config) *Controller {
config: usersCfg,
}
}

// New renders the new user form
func (u *Controller) New(c *fiber.Ctx) error {
var session model.User
if val, ok := c.Locals("Session").(model.User); ok {
session = val
}

if session.Role != model.RoleAdmin {
return fiber.ErrForbidden
}

user := model.User{
WordsPerMinute: u.config.WordsPerMinute,
}
return c.Render("users/new", fiber.Map{
"Title": "Add user",
"MinPasswordLength": u.config.MinPasswordLength,
"User": user,
"Errors": map[string]string{},
}, "layout")
}
9 changes: 0 additions & 9 deletions internal/webserver/controller/user/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,6 @@ import (

// Create gathers information coming from the new user form and creates a new user
func (u *Controller) Create(c *fiber.Ctx) error {
var session model.User
if val, ok := c.Locals("Session").(model.User); ok {
session = val
}

if session.Role != model.RoleAdmin {
return fiber.ErrForbidden
}

role, _ := strconv.Atoi(c.FormValue("role"))
user := model.User{
Name: c.FormValue("name"),
Expand Down
7 changes: 0 additions & 7 deletions internal/webserver/controller/user/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,11 @@ import (
"fmt"

"github.com/gofiber/fiber/v2"
"github.com/svera/coreander/v3/internal/webserver/jwtclaimsreader"
"github.com/svera/coreander/v3/internal/webserver/model"
)

// Delete removes a user from the database
func (u *Controller) Delete(c *fiber.Ctx) error {
session := jwtclaimsreader.SessionData(c)

if session.Role != model.RoleAdmin {
return fiber.ErrForbidden
}

user, err := u.repository.FindByUuid(c.FormValue("uuid"))
if err != nil {
return fiber.ErrNotFound
Expand Down
9 changes: 0 additions & 9 deletions internal/webserver/controller/user/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,6 @@ import (

// List list all users registered in the database
func (u *Controller) List(c *fiber.Ctx) error {
var session model.User
if val, ok := c.Locals("Session").(model.User); ok {
session = val
}

if session.Role != model.RoleAdmin {
return fiber.ErrForbidden
}

page, err := strconv.Atoi(c.Query("page"))
if err != nil {
page = 1
Expand Down
Loading

0 comments on commit f30fa5b

Please sign in to comment.