mirror of
https://github.com/pocket-id/pocket-id.git
synced 2026-08-24 21:17:31 +00:00
limits
This commit is contained in:
@@ -161,7 +161,7 @@ func registerRoutes(r *gin.Engine, db *gorm.DB, svc *services, rateLimitServices
|
||||
controller.NewOidcController(api, authMiddleware, fileSizeLimitMiddleware, svc.oidcService)
|
||||
controller.NewUserController(api, authMiddleware, rateLimitMiddleware, svc.userService, svc.oneTimeAccessService, svc.webauthnModule, svc.appConfigService)
|
||||
controller.NewAppConfigController(api, authMiddleware, svc.appConfigService, svc.emailService, svc.ldapService)
|
||||
controller.NewAppImagesController(api, authMiddleware, svc.appImagesService)
|
||||
controller.NewAppImagesController(api, authMiddleware, fileSizeLimitMiddleware, svc.appImagesService)
|
||||
controller.NewAuditLogController(api, svc.auditLogService, authMiddleware)
|
||||
controller.NewUserGroupController(api, authMiddleware, svc.userGroupService)
|
||||
svc.apiModule.RegisterRoutes(api, authMiddleware.Huma(api))
|
||||
|
||||
@@ -43,9 +43,10 @@ type imageOutput struct {
|
||||
Body func(huma.Context)
|
||||
}
|
||||
|
||||
func NewAppImagesController(api huma.API, authMiddleware *middleware.AuthMiddleware, appImagesService *service.AppImagesService) {
|
||||
func NewAppImagesController(api huma.API, authMiddleware *middleware.AuthMiddleware, fileSizeLimitMiddleware *middleware.FileSizeLimitMiddleware, appImagesService *service.AppImagesService) {
|
||||
controller := &AppImagesController{appImagesService: appImagesService}
|
||||
auth := authMiddleware.Huma(api)
|
||||
uploadLimit := httpapi.WithMiddleware(fileSizeLimitMiddleware.Huma(api, 2<<20))
|
||||
|
||||
httpapi.Register(api, huma.Operation{
|
||||
OperationID: "get-application-logo",
|
||||
@@ -94,7 +95,7 @@ func NewAppImagesController(api huma.API, authMiddleware *middleware.AuthMiddlew
|
||||
Summary: "Update logo",
|
||||
Tags: []string{"Application Images"},
|
||||
DefaultStatus: http.StatusNoContent,
|
||||
}, controller.updateLogoHandler, auth)
|
||||
}, controller.updateLogoHandler, auth, uploadLimit)
|
||||
|
||||
httpapi.Register(api, huma.Operation{
|
||||
OperationID: "update-email-logo",
|
||||
@@ -103,7 +104,7 @@ func NewAppImagesController(api huma.API, authMiddleware *middleware.AuthMiddlew
|
||||
Summary: "Update email logo",
|
||||
Tags: []string{"Application Images"},
|
||||
DefaultStatus: http.StatusNoContent,
|
||||
}, controller.updateEmailLogoHandler, auth)
|
||||
}, controller.updateEmailLogoHandler, auth, uploadLimit)
|
||||
|
||||
httpapi.Register(api, huma.Operation{
|
||||
OperationID: "update-background-image",
|
||||
@@ -112,7 +113,7 @@ func NewAppImagesController(api huma.API, authMiddleware *middleware.AuthMiddlew
|
||||
Summary: "Update background image",
|
||||
Tags: []string{"Application Images"},
|
||||
DefaultStatus: http.StatusNoContent,
|
||||
}, controller.updateBackgroundImageHandler, auth)
|
||||
}, controller.updateBackgroundImageHandler, auth, uploadLimit)
|
||||
|
||||
httpapi.Register(api, huma.Operation{
|
||||
OperationID: "update-favicon",
|
||||
@@ -121,7 +122,7 @@ func NewAppImagesController(api huma.API, authMiddleware *middleware.AuthMiddlew
|
||||
Summary: "Update favicon",
|
||||
Tags: []string{"Application Images"},
|
||||
DefaultStatus: http.StatusNoContent,
|
||||
}, controller.updateFaviconHandler, auth)
|
||||
}, controller.updateFaviconHandler, auth, uploadLimit)
|
||||
|
||||
httpapi.Register(api, huma.Operation{
|
||||
OperationID: "update-default-profile-picture",
|
||||
@@ -130,7 +131,7 @@ func NewAppImagesController(api huma.API, authMiddleware *middleware.AuthMiddlew
|
||||
Summary: "Update default profile picture",
|
||||
Tags: []string{"Application Images"},
|
||||
DefaultStatus: http.StatusNoContent,
|
||||
}, controller.updateDefaultProfilePicture, auth)
|
||||
}, controller.updateDefaultProfilePicture, auth, uploadLimit)
|
||||
|
||||
httpapi.Register(api, huma.Operation{
|
||||
OperationID: "delete-background-image",
|
||||
|
||||
@@ -211,6 +211,8 @@ func (s *OidcService) UpdateClient(ctx context.Context, clientID string, input d
|
||||
}
|
||||
|
||||
func updateOIDCClientModelFromDto(client *model.OidcClient, input *dto.OidcClientUpdateDto) {
|
||||
dto.Normalize(input)
|
||||
|
||||
// Base fields
|
||||
client.Name = input.Name
|
||||
client.Description = input.Description
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"golang.org/x/text/unicode/norm"
|
||||
|
||||
"github.com/pocket-id/pocket-id/backend/internal/common"
|
||||
"github.com/pocket-id/pocket-id/backend/internal/dto"
|
||||
@@ -457,10 +458,11 @@ func TestOidcService_CreateClient_withDescription(t *testing.T) {
|
||||
s, err := NewOidcService(db, nil, nil, nil, nil, nil, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
description := "A test client description"
|
||||
name := norm.NFD.String("Tést Client")
|
||||
description := norm.NFD.String("A café client description")
|
||||
input := dto.OidcClientCreateDto{
|
||||
OidcClientUpdateDto: dto.OidcClientUpdateDto{
|
||||
Name: "Test Client",
|
||||
Name: name,
|
||||
Description: description,
|
||||
CallbackURLs: []string{"https://example.com/callback"},
|
||||
},
|
||||
@@ -473,7 +475,8 @@ func TestOidcService_CreateClient_withDescription(t *testing.T) {
|
||||
err = db.First(&fetched, "id = ?", client.ID).Error
|
||||
require.NoError(t, err)
|
||||
require.NotEmpty(t, fetched.Description)
|
||||
assert.Equal(t, description, fetched.Description)
|
||||
assert.Equal(t, norm.NFC.String(name), fetched.Name)
|
||||
assert.Equal(t, norm.NFC.String(description), fetched.Description)
|
||||
}
|
||||
|
||||
func TestOidcService_CreateClient_withoutDescription(t *testing.T) {
|
||||
@@ -513,7 +516,7 @@ func TestOidcService_UpdateClient_description(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
// Update with a description
|
||||
description := "Updated description"
|
||||
description := norm.NFD.String("Updated café description")
|
||||
input := dto.OidcClientUpdateDto{
|
||||
Name: "Test Client",
|
||||
Description: description,
|
||||
@@ -527,7 +530,7 @@ func TestOidcService_UpdateClient_description(t *testing.T) {
|
||||
err = db.First(&fetched, "id = ?", client.ID).Error
|
||||
require.NoError(t, err)
|
||||
require.NotEmpty(t, fetched.Description)
|
||||
assert.Equal(t, description, fetched.Description)
|
||||
assert.Equal(t, norm.NFC.String(description), fetched.Description)
|
||||
|
||||
// Update to clear the description
|
||||
input.Description = ""
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/danielgtaylor/huma/v2"
|
||||
"github.com/gin-gonic/gin"
|
||||
@@ -197,3 +198,40 @@ func TestRegisterAppliesDecoratorsInOrder(t *testing.T) {
|
||||
require.Equal(t, http.StatusNoContent, response.Code)
|
||||
require.Equal(t, []string{"first", "second", "handler"}, order)
|
||||
}
|
||||
|
||||
func TestRegisterPreservesBodyLimitConfiguration(t *testing.T) {
|
||||
router, api := newTestAPI(t)
|
||||
|
||||
Register(api, huma.Operation{
|
||||
OperationID: "test-default-body-limits",
|
||||
Method: http.MethodPost,
|
||||
Path: "/api/test-default-body-limits",
|
||||
}, func(context.Context, *testInput) (*testOutput, error) {
|
||||
return &testOutput{}, nil
|
||||
})
|
||||
|
||||
defaultOperation := api.OpenAPI().Paths["/api/test-default-body-limits"].Post
|
||||
require.Equal(t, int64(1<<20), defaultOperation.MaxBodyBytes)
|
||||
require.Equal(t, 5*time.Second, defaultOperation.BodyReadTimeout)
|
||||
|
||||
request := httptest.NewRequestWithContext(t.Context(), http.MethodPost, "/api/test-default-body-limits", strings.NewReader(`{"name":"`+strings.Repeat("x", 1<<20)+`"}`))
|
||||
request.Header.Set("Content-Type", "application/json")
|
||||
response := httptest.NewRecorder()
|
||||
router.ServeHTTP(response, request)
|
||||
require.Equal(t, http.StatusRequestEntityTooLarge, response.Code)
|
||||
require.JSONEq(t, `{"error":"Request body is too large limit=1048576 bytes"}`, response.Body.String())
|
||||
|
||||
Register(api, huma.Operation{
|
||||
OperationID: "test-unlimited-body",
|
||||
Method: http.MethodPost,
|
||||
Path: "/api/test-unlimited-body",
|
||||
MaxBodyBytes: -1,
|
||||
BodyReadTimeout: -1,
|
||||
}, func(context.Context, *testInput) (*testOutput, error) {
|
||||
return &testOutput{}, nil
|
||||
})
|
||||
|
||||
unlimitedOperation := api.OpenAPI().Paths["/api/test-unlimited-body"].Post
|
||||
require.Equal(t, int64(-1), unlimitedOperation.MaxBodyBytes)
|
||||
require.Equal(t, time.Duration(-1), unlimitedOperation.BodyReadTimeout)
|
||||
}
|
||||
|
||||
@@ -19,12 +19,6 @@ func Register[I, O any](api huma.API, operation huma.Operation, handler func(con
|
||||
decorator(&operation)
|
||||
}
|
||||
|
||||
if operation.MaxBodyBytes == 0 {
|
||||
operation.MaxBodyBytes = -1
|
||||
}
|
||||
if operation.BodyReadTimeout == 0 {
|
||||
operation.BodyReadTimeout = -1
|
||||
}
|
||||
huma.Register(api, operation, func(ctx context.Context, input *I) (*O, error) {
|
||||
output, err := handler(ctx, input)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user