This commit is contained in:
Kyle Mendell
2026-07-13 11:12:46 -05:00
parent 00d2b0fea9
commit c87b9a97aa
6 changed files with 56 additions and 18 deletions
@@ -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",
+2
View File
@@ -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 = ""
+38
View File
@@ -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)
}
-6
View File
@@ -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 {