mirror of
https://github.com/pocket-id/pocket-id.git
synced 2026-07-22 12:41:27 +02:00
Remove the AppConfigMiddleware that stored an app-config resolver in the request context and the FromCtx helper that read it back downstream. Handlers now load the app config from AppConfigService and pass it as an explicit argument to the service methods that need it, which then forward it further down the call chain. The webauthn and usersignup modules gain an AppConfigResolver dependency so their handlers can load the config the same way. The email SendEmail and LDAP SyncAll helpers drop their context-based variants in favor of the explicit-config versions. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YZ6SoJpmnLggZqactXxrak
187 lines
5.9 KiB
Go
187 lines
5.9 KiB
Go
package controller
|
|
|
|
import (
|
|
"net/http"
|
|
"strconv"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/pocket-id/pocket-id/backend/internal/appconfig"
|
|
"github.com/pocket-id/pocket-id/backend/internal/common"
|
|
"github.com/pocket-id/pocket-id/backend/internal/dto"
|
|
"github.com/pocket-id/pocket-id/backend/internal/middleware"
|
|
"github.com/pocket-id/pocket-id/backend/internal/service"
|
|
"github.com/pocket-id/pocket-id/backend/internal/tracing"
|
|
)
|
|
|
|
// NewAppConfigController creates a new controller for application configuration endpoints
|
|
// @Summary Create a new application configuration controller
|
|
// @Description Initialize routes for application configuration
|
|
// @Tags Application Configuration
|
|
func NewAppConfigController(
|
|
group *gin.RouterGroup,
|
|
authMiddleware *middleware.AuthMiddleware,
|
|
appConfigService *appconfig.AppConfigService,
|
|
emailService *service.EmailService,
|
|
ldapService *service.LdapService,
|
|
) {
|
|
|
|
acc := &AppConfigController{
|
|
appConfigService: appConfigService,
|
|
emailService: emailService,
|
|
ldapService: ldapService,
|
|
}
|
|
group.GET("/application-configuration", acc.listAppConfigHandler)
|
|
group.GET("/application-configuration/all", authMiddleware.Add(), acc.listAllAppConfigHandler)
|
|
group.PUT("/application-configuration", authMiddleware.Add(), acc.updateAppConfigHandler)
|
|
|
|
group.POST("/application-configuration/test-email", authMiddleware.Add(), acc.testEmailHandler)
|
|
group.POST("/application-configuration/sync-ldap", authMiddleware.Add(), acc.syncLdapHandler)
|
|
}
|
|
|
|
type AppConfigController struct {
|
|
appConfigService *appconfig.AppConfigService
|
|
emailService *service.EmailService
|
|
ldapService *service.LdapService
|
|
}
|
|
|
|
// listAppConfigHandler godoc
|
|
// @Summary List public application configurations
|
|
// @Description Get all public application configurations
|
|
// @Tags Application Configuration
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Success 200 {array} dto.PublicAppConfigVariableDto
|
|
// @Router /api/application-configuration [get]
|
|
func (acc *AppConfigController) listAppConfigHandler(c *gin.Context) {
|
|
dbConfig, err := acc.appConfigService.GetConfig(c.Request.Context())
|
|
if err != nil {
|
|
_ = c.Error(err)
|
|
return
|
|
}
|
|
configuration := dbConfig.ToAppConfigVariableSlice(false, true)
|
|
|
|
var configVariablesDto []dto.PublicAppConfigVariableDto
|
|
if err := dto.MapStructList(configuration, &configVariablesDto); err != nil {
|
|
_ = c.Error(err)
|
|
return
|
|
}
|
|
|
|
// Manually add uiConfigDisabled which isn't in the database but defined with an environment variable
|
|
configVariablesDto = append(configVariablesDto, dto.PublicAppConfigVariableDto{
|
|
Key: "uiConfigDisabled",
|
|
Value: strconv.FormatBool(common.EnvConfig.UiConfigDisabled),
|
|
Type: "boolean",
|
|
})
|
|
|
|
// Manually add tracingEnabled, derived from the OTel environment, so the frontend only exports traces when the backend can forward them to a collector
|
|
configVariablesDto = append(configVariablesDto, dto.PublicAppConfigVariableDto{
|
|
Key: "tracingEnabled",
|
|
Value: strconv.FormatBool(tracing.FrontendTracingEnabled()),
|
|
Type: "boolean",
|
|
})
|
|
|
|
c.JSON(http.StatusOK, configVariablesDto)
|
|
}
|
|
|
|
// listAllAppConfigHandler godoc
|
|
// @Summary List all application configurations
|
|
// @Description Get all application configurations including private ones
|
|
// @Tags Application Configuration
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Success 200 {array} dto.AppConfigVariableDto
|
|
// @Router /api/application-configuration/all [get]
|
|
func (acc *AppConfigController) listAllAppConfigHandler(c *gin.Context) {
|
|
dbConfig, err := acc.appConfigService.GetConfig(c.Request.Context())
|
|
if err != nil {
|
|
_ = c.Error(err)
|
|
return
|
|
}
|
|
configuration := dbConfig.ToAppConfigVariableSlice(true, true)
|
|
|
|
var configVariablesDto []dto.AppConfigVariableDto
|
|
if err := dto.MapStructList(configuration, &configVariablesDto); err != nil {
|
|
_ = c.Error(err)
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, configVariablesDto)
|
|
}
|
|
|
|
// updateAppConfigHandler godoc
|
|
// @Summary Update application configurations
|
|
// @Description Update application configuration settings
|
|
// @Tags Application Configuration
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param body body dto.AppConfigUpdateDto true "Application Configuration"
|
|
// @Success 200 {array} dto.AppConfigVariableDto
|
|
// @Router /api/application-configuration [put]
|
|
func (acc *AppConfigController) updateAppConfigHandler(c *gin.Context) {
|
|
var input dto.AppConfigUpdateDto
|
|
if err := dto.ShouldBindWithNormalizedJSON(c, &input); err != nil {
|
|
_ = c.Error(err)
|
|
return
|
|
}
|
|
|
|
savedConfigVariables, err := acc.appConfigService.UpdateAppConfig(c.Request.Context(), input)
|
|
if err != nil {
|
|
_ = c.Error(err)
|
|
return
|
|
}
|
|
|
|
var configVariablesDto []dto.AppConfigVariableDto
|
|
if err := dto.MapStructList(savedConfigVariables, &configVariablesDto); err != nil {
|
|
_ = c.Error(err)
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, configVariablesDto)
|
|
}
|
|
|
|
// syncLdapHandler godoc
|
|
// @Summary Synchronize LDAP
|
|
// @Description Manually trigger LDAP synchronization
|
|
// @Tags Application Configuration
|
|
// @Success 204 "No Content"
|
|
// @Router /api/application-configuration/sync-ldap [post]
|
|
func (acc *AppConfigController) syncLdapHandler(c *gin.Context) {
|
|
dbConfig, err := acc.appConfigService.GetConfig(c.Request.Context())
|
|
if err != nil {
|
|
_ = c.Error(err)
|
|
return
|
|
}
|
|
|
|
err = acc.ldapService.SyncAll(c.Request.Context(), dbConfig)
|
|
if err != nil {
|
|
_ = c.Error(err)
|
|
return
|
|
}
|
|
|
|
c.Status(http.StatusNoContent)
|
|
}
|
|
|
|
// testEmailHandler godoc
|
|
// @Summary Send test email
|
|
// @Description Send a test email to verify email configuration
|
|
// @Tags Application Configuration
|
|
// @Success 204 "No Content"
|
|
// @Router /api/application-configuration/test-email [post]
|
|
func (acc *AppConfigController) testEmailHandler(c *gin.Context) {
|
|
dbConfig, err := acc.appConfigService.GetConfig(c.Request.Context())
|
|
if err != nil {
|
|
_ = c.Error(err)
|
|
return
|
|
}
|
|
|
|
userID := c.GetString("userID")
|
|
|
|
err = acc.emailService.SendTestEmail(c.Request.Context(), dbConfig, userID)
|
|
if err != nil {
|
|
_ = c.Error(err)
|
|
return
|
|
}
|
|
|
|
c.Status(http.StatusNoContent)
|
|
}
|