mirror of
https://github.com/truewhile/MeBox.git
synced 2026-09-29 03:26:37 +08:00
fix: add field whitelist to site update, fix HTTP status codes in site handlers
- SiteService.Update: whitelist updatable fields to prevent injection of id, created_at, deleted_at, login_status, upload_bytes, download_bytes - createSiteHandler: return 201 Created (was 200 OK) - siteSearchHandler: return 500 for infra errors (was 400) Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
@@ -102,7 +102,7 @@ func createSiteHandler(svc *service.Container) gin.HandlerFunc {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, site)
|
||||
c.JSON(http.StatusCreated, site)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,7 +156,7 @@ func siteSearchHandler(svc *service.Container) gin.HandlerFunc {
|
||||
}
|
||||
results, err := svc.Site.Search(c.Request.Context(), keyword)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{"items": results, "total": len(results)})
|
||||
|
||||
@@ -213,20 +213,53 @@ func (s *SiteService) FindByID(ctx context.Context, id string) (*model.Site, err
|
||||
return &site, err
|
||||
}
|
||||
|
||||
// siteUpdatableFields is the whitelist of columns that may be patched via
|
||||
// the update endpoint. Fields like id, created_at, deleted_at, login_status,
|
||||
// upload_bytes, download_bytes are excluded to prevent injection.
|
||||
var siteUpdatableFields = map[string]bool{
|
||||
"name": true,
|
||||
"url": true,
|
||||
"type": true,
|
||||
"auth_type": true,
|
||||
"api_key": true,
|
||||
"cookie": true,
|
||||
"auth_header": true,
|
||||
"user_agent": true,
|
||||
"rss_url": true,
|
||||
"timeout": true,
|
||||
"priority": true,
|
||||
"use_proxy": true,
|
||||
"rate_limit": true,
|
||||
"browser_emulation": true,
|
||||
"downloader": true,
|
||||
"enabled": true,
|
||||
"is_default": true,
|
||||
"extra": true,
|
||||
}
|
||||
|
||||
// Update applies a partial patch to an existing site.
|
||||
func (s *SiteService) Update(ctx context.Context, id string, updates map[string]any) error {
|
||||
if id == "" {
|
||||
return errors.New("site id required")
|
||||
}
|
||||
if raw, ok := updates["url"].(string); ok {
|
||||
updates["url"] = strings.TrimRight(strings.TrimSpace(raw), "/")
|
||||
}
|
||||
for _, key := range []string{"api_key", "cookie", "auth_header"} {
|
||||
if raw, ok := updates[key].(string); ok && strings.TrimSpace(raw) == "" {
|
||||
delete(updates, key)
|
||||
filtered := make(map[string]any, len(updates))
|
||||
for k, v := range updates {
|
||||
if siteUpdatableFields[k] {
|
||||
filtered[k] = v
|
||||
}
|
||||
}
|
||||
return s.repo.DB.WithContext(ctx).Model(&model.Site{}).Where("id = ?", id).Updates(updates).Error
|
||||
if len(filtered) == 0 {
|
||||
return errors.New("no valid fields to update")
|
||||
}
|
||||
if raw, ok := filtered["url"].(string); ok {
|
||||
filtered["url"] = strings.TrimRight(strings.TrimSpace(raw), "/")
|
||||
}
|
||||
for _, key := range []string{"api_key", "cookie", "auth_header"} {
|
||||
if raw, ok := filtered[key].(string); ok && strings.TrimSpace(raw) == "" {
|
||||
delete(filtered, key)
|
||||
}
|
||||
}
|
||||
return s.repo.DB.WithContext(ctx).Model(&model.Site{}).Where("id = ?", id).Updates(filtered).Error
|
||||
}
|
||||
|
||||
// Delete removes a site.
|
||||
|
||||
Reference in New Issue
Block a user