mirror of
https://github.com/pocket-id/pocket-id.git
synced 2026-10-04 08:49:03 +02:00
refactor: standardize API error handling (#1635)
This commit is contained in:
@@ -9,6 +9,7 @@ import (
|
||||
"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/httpserver"
|
||||
"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"
|
||||
@@ -35,12 +36,12 @@ func NewAppConfigController(
|
||||
emailSender: emailSender,
|
||||
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.GET("/application-configuration", httpserver.Handle(acc.listAppConfigHandler))
|
||||
group.GET("/application-configuration/all", authMiddleware.Add(), httpserver.Handle(acc.listAllAppConfigHandler))
|
||||
group.PUT("/application-configuration", authMiddleware.Add(), httpserver.Handle(acc.updateAppConfigHandler))
|
||||
|
||||
group.POST("/application-configuration/test-email", authMiddleware.Add(), acc.testEmailHandler)
|
||||
group.POST("/application-configuration/sync-ldap", authMiddleware.Add(), acc.syncLdapHandler)
|
||||
group.POST("/application-configuration/test-email", authMiddleware.Add(), httpserver.Handle(acc.testEmailHandler))
|
||||
group.POST("/application-configuration/sync-ldap", authMiddleware.Add(), httpserver.Handle(acc.syncLdapHandler))
|
||||
}
|
||||
|
||||
type AppConfigController struct {
|
||||
@@ -57,18 +58,16 @@ type AppConfigController struct {
|
||||
// @Produce json
|
||||
// @Success 200 {array} dto.PublicAppConfigVariableDto
|
||||
// @Router /api/application-configuration [get]
|
||||
func (acc *AppConfigController) listAppConfigHandler(c *gin.Context) {
|
||||
func (acc *AppConfigController) listAppConfigHandler(c *gin.Context) error {
|
||||
dbConfig, err := acc.appConfigService.GetConfig(c.Request.Context())
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
configuration := dbConfig.ToAppConfigVariableSlice(false, true)
|
||||
|
||||
var configVariablesDto []dto.PublicAppConfigVariableDto
|
||||
if err := dto.MapStructList(configuration, &configVariablesDto); err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
// Manually add uiConfigDisabled which isn't in the database but defined with an environment variable
|
||||
@@ -85,6 +84,7 @@ func (acc *AppConfigController) listAppConfigHandler(c *gin.Context) {
|
||||
})
|
||||
|
||||
c.JSON(http.StatusOK, configVariablesDto)
|
||||
return nil
|
||||
}
|
||||
|
||||
// listAllAppConfigHandler godoc
|
||||
@@ -95,21 +95,20 @@ func (acc *AppConfigController) listAppConfigHandler(c *gin.Context) {
|
||||
// @Produce json
|
||||
// @Success 200 {array} dto.AppConfigVariableDto
|
||||
// @Router /api/application-configuration/all [get]
|
||||
func (acc *AppConfigController) listAllAppConfigHandler(c *gin.Context) {
|
||||
func (acc *AppConfigController) listAllAppConfigHandler(c *gin.Context) error {
|
||||
dbConfig, err := acc.appConfigService.GetConfig(c.Request.Context())
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
configuration := dbConfig.ToAppConfigVariableSlice(true, true)
|
||||
|
||||
var configVariablesDto []dto.AppConfigVariableDto
|
||||
if err := dto.MapStructList(configuration, &configVariablesDto); err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, configVariablesDto)
|
||||
return nil
|
||||
}
|
||||
|
||||
// updateAppConfigHandler godoc
|
||||
@@ -121,26 +120,24 @@ func (acc *AppConfigController) listAllAppConfigHandler(c *gin.Context) {
|
||||
// @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) {
|
||||
func (acc *AppConfigController) updateAppConfigHandler(c *gin.Context) error {
|
||||
var input dto.AppConfigUpdateDto
|
||||
if err := dto.ShouldBindWithNormalizedJSON(c, &input); err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
if err := httpserver.BindJSON(c, &input); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
savedConfigVariables, err := acc.appConfigService.UpdateAppConfig(c.Request.Context(), input)
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
var configVariablesDto []dto.AppConfigVariableDto
|
||||
if err := dto.MapStructList(savedConfigVariables, &configVariablesDto); err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, configVariablesDto)
|
||||
return nil
|
||||
}
|
||||
|
||||
// syncLdapHandler godoc
|
||||
@@ -149,20 +146,19 @@ func (acc *AppConfigController) updateAppConfigHandler(c *gin.Context) {
|
||||
// @Tags Application Configuration
|
||||
// @Success 204 "No Content"
|
||||
// @Router /api/application-configuration/sync-ldap [post]
|
||||
func (acc *AppConfigController) syncLdapHandler(c *gin.Context) {
|
||||
func (acc *AppConfigController) syncLdapHandler(c *gin.Context) error {
|
||||
dbConfig, err := acc.appConfigService.GetConfig(c.Request.Context())
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
err = acc.ldapService.SyncAll(c.Request.Context(), dbConfig)
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
c.Status(http.StatusNoContent)
|
||||
return nil
|
||||
}
|
||||
|
||||
// testEmailHandler godoc
|
||||
@@ -171,20 +167,19 @@ func (acc *AppConfigController) syncLdapHandler(c *gin.Context) {
|
||||
// @Tags Application Configuration
|
||||
// @Success 204 "No Content"
|
||||
// @Router /api/application-configuration/test-email [post]
|
||||
func (acc *AppConfigController) testEmailHandler(c *gin.Context) {
|
||||
func (acc *AppConfigController) testEmailHandler(c *gin.Context) error {
|
||||
dbConfig, err := acc.appConfigService.GetConfig(c.Request.Context())
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
userID := c.GetString("userID")
|
||||
|
||||
err = acc.emailSender.SendTestEmail(c.Request.Context(), dbConfig, userID)
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
c.Status(http.StatusNoContent)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -9,7 +9,8 @@ import (
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"github.com/pocket-id/pocket-id/backend/internal/common"
|
||||
"github.com/pocket-id/pocket-id/backend/internal/apperror"
|
||||
"github.com/pocket-id/pocket-id/backend/internal/httpserver"
|
||||
"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/utils"
|
||||
@@ -24,20 +25,20 @@ func NewAppImagesController(
|
||||
appImagesService: appImagesService,
|
||||
}
|
||||
|
||||
group.GET("/application-images/logo", controller.getLogoHandler)
|
||||
group.GET("/application-images/email", controller.getEmailLogoHandler)
|
||||
group.GET("/application-images/background", controller.getBackgroundImageHandler)
|
||||
group.GET("/application-images/favicon", controller.getFaviconHandler)
|
||||
group.GET("/application-images/default-profile-picture", authMiddleware.Add(), controller.getDefaultProfilePicture)
|
||||
group.GET("/application-images/logo", httpserver.Handle(controller.getLogoHandler))
|
||||
group.GET("/application-images/email", httpserver.Handle(controller.getEmailLogoHandler))
|
||||
group.GET("/application-images/background", httpserver.Handle(controller.getBackgroundImageHandler))
|
||||
group.GET("/application-images/favicon", httpserver.Handle(controller.getFaviconHandler))
|
||||
group.GET("/application-images/default-profile-picture", authMiddleware.Add(), httpserver.Handle(controller.getDefaultProfilePicture))
|
||||
|
||||
group.PUT("/application-images/logo", authMiddleware.Add(), controller.updateLogoHandler)
|
||||
group.PUT("/application-images/email", authMiddleware.Add(), controller.updateEmailLogoHandler)
|
||||
group.PUT("/application-images/background", authMiddleware.Add(), controller.updateBackgroundImageHandler)
|
||||
group.PUT("/application-images/favicon", authMiddleware.Add(), controller.updateFaviconHandler)
|
||||
group.PUT("/application-images/default-profile-picture", authMiddleware.Add(), controller.updateDefaultProfilePicture)
|
||||
group.PUT("/application-images/logo", authMiddleware.Add(), httpserver.Handle(controller.updateLogoHandler))
|
||||
group.PUT("/application-images/email", authMiddleware.Add(), httpserver.Handle(controller.updateEmailLogoHandler))
|
||||
group.PUT("/application-images/background", authMiddleware.Add(), httpserver.Handle(controller.updateBackgroundImageHandler))
|
||||
group.PUT("/application-images/favicon", authMiddleware.Add(), httpserver.Handle(controller.updateFaviconHandler))
|
||||
group.PUT("/application-images/default-profile-picture", authMiddleware.Add(), httpserver.Handle(controller.updateDefaultProfilePicture))
|
||||
|
||||
group.DELETE("/application-images/background", authMiddleware.Add(), controller.deleteBackgroundImageHandler)
|
||||
group.DELETE("/application-images/default-profile-picture", authMiddleware.Add(), controller.deleteDefaultProfilePicture)
|
||||
group.DELETE("/application-images/background", authMiddleware.Add(), httpserver.Handle(controller.deleteBackgroundImageHandler))
|
||||
group.DELETE("/application-images/default-profile-picture", authMiddleware.Add(), httpserver.Handle(controller.deleteDefaultProfilePicture))
|
||||
}
|
||||
|
||||
type AppImagesController struct {
|
||||
@@ -54,14 +55,14 @@ type AppImagesController struct {
|
||||
// @Produce image/svg+xml
|
||||
// @Success 200 {file} binary "Logo image"
|
||||
// @Router /api/application-images/logo [get]
|
||||
func (c *AppImagesController) getLogoHandler(ctx *gin.Context) {
|
||||
func (c *AppImagesController) getLogoHandler(ctx *gin.Context) error {
|
||||
lightLogo, _ := strconv.ParseBool(ctx.DefaultQuery("light", "true"))
|
||||
imageName := "logoLight"
|
||||
if !lightLogo {
|
||||
imageName = "logoDark"
|
||||
}
|
||||
|
||||
c.getImage(ctx, imageName)
|
||||
return c.getImage(ctx, imageName)
|
||||
}
|
||||
|
||||
// getEmailLogoHandler godoc
|
||||
@@ -72,8 +73,8 @@ func (c *AppImagesController) getLogoHandler(ctx *gin.Context) {
|
||||
// @Produce image/jpeg
|
||||
// @Success 200 {file} binary "Email logo image"
|
||||
// @Router /api/application-images/email [get]
|
||||
func (c *AppImagesController) getEmailLogoHandler(ctx *gin.Context) {
|
||||
c.getImage(ctx, "logoEmail")
|
||||
func (c *AppImagesController) getEmailLogoHandler(ctx *gin.Context) error {
|
||||
return c.getImage(ctx, "logoEmail")
|
||||
}
|
||||
|
||||
// getBackgroundImageHandler godoc
|
||||
@@ -84,8 +85,8 @@ func (c *AppImagesController) getEmailLogoHandler(ctx *gin.Context) {
|
||||
// @Produce image/jpeg
|
||||
// @Success 200 {file} binary "Background image"
|
||||
// @Router /api/application-images/background [get]
|
||||
func (c *AppImagesController) getBackgroundImageHandler(ctx *gin.Context) {
|
||||
c.getImage(ctx, "background")
|
||||
func (c *AppImagesController) getBackgroundImageHandler(ctx *gin.Context) error {
|
||||
return c.getImage(ctx, "background")
|
||||
}
|
||||
|
||||
// getFaviconHandler godoc
|
||||
@@ -95,8 +96,8 @@ func (c *AppImagesController) getBackgroundImageHandler(ctx *gin.Context) {
|
||||
// @Produce image/x-icon
|
||||
// @Success 200 {file} binary "Favicon image"
|
||||
// @Router /api/application-images/favicon [get]
|
||||
func (c *AppImagesController) getFaviconHandler(ctx *gin.Context) {
|
||||
c.getImage(ctx, "favicon")
|
||||
func (c *AppImagesController) getFaviconHandler(ctx *gin.Context) error {
|
||||
return c.getImage(ctx, "favicon")
|
||||
}
|
||||
|
||||
// getDefaultProfilePicture godoc
|
||||
@@ -107,8 +108,8 @@ func (c *AppImagesController) getFaviconHandler(ctx *gin.Context) {
|
||||
// @Produce image/jpeg
|
||||
// @Success 200 {file} binary "Default profile picture image"
|
||||
// @Router /api/application-images/default-profile-picture [get]
|
||||
func (c *AppImagesController) getDefaultProfilePicture(ctx *gin.Context) {
|
||||
c.getImage(ctx, "default-profile-picture")
|
||||
func (c *AppImagesController) getDefaultProfilePicture(ctx *gin.Context) error {
|
||||
return c.getImage(ctx, "default-profile-picture")
|
||||
}
|
||||
|
||||
// updateLogoHandler godoc
|
||||
@@ -120,11 +121,10 @@ func (c *AppImagesController) getDefaultProfilePicture(ctx *gin.Context) {
|
||||
// @Param file formData file true "Logo image file"
|
||||
// @Success 204 "No Content"
|
||||
// @Router /api/application-images/logo [put]
|
||||
func (c *AppImagesController) updateLogoHandler(ctx *gin.Context) {
|
||||
file, err := ctx.FormFile("file")
|
||||
func (c *AppImagesController) updateLogoHandler(ctx *gin.Context) error {
|
||||
file, err := httpserver.FormFile(ctx, "file")
|
||||
if err != nil {
|
||||
_ = ctx.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
lightLogo, _ := strconv.ParseBool(ctx.DefaultQuery("light", "true"))
|
||||
@@ -134,11 +134,11 @@ func (c *AppImagesController) updateLogoHandler(ctx *gin.Context) {
|
||||
}
|
||||
|
||||
if err := c.appImagesService.UpdateImage(ctx.Request.Context(), file, imageName); err != nil {
|
||||
_ = ctx.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
ctx.Status(http.StatusNoContent)
|
||||
return nil
|
||||
}
|
||||
|
||||
// updateEmailLogoHandler godoc
|
||||
@@ -149,27 +149,25 @@ func (c *AppImagesController) updateLogoHandler(ctx *gin.Context) {
|
||||
// @Param file formData file true "Email logo image file"
|
||||
// @Success 204 "No Content"
|
||||
// @Router /api/application-images/email [put]
|
||||
func (c *AppImagesController) updateEmailLogoHandler(ctx *gin.Context) {
|
||||
file, err := ctx.FormFile("file")
|
||||
func (c *AppImagesController) updateEmailLogoHandler(ctx *gin.Context) error {
|
||||
file, err := httpserver.FormFile(ctx, "file")
|
||||
if err != nil {
|
||||
_ = ctx.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
fileType := utils.GetFileExtension(file.Filename)
|
||||
mimeType := utils.GetImageMimeType(fileType)
|
||||
|
||||
if mimeType != "image/png" && mimeType != "image/jpeg" {
|
||||
_ = ctx.Error(&common.WrongFileTypeError{ExpectedFileType: ".png or .jpg/jpeg"})
|
||||
return
|
||||
return apperror.UnsupportedFileType("PNG or JPEG")
|
||||
}
|
||||
|
||||
if err := c.appImagesService.UpdateImage(ctx.Request.Context(), file, "logoEmail"); err != nil {
|
||||
_ = ctx.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
ctx.Status(http.StatusNoContent)
|
||||
return nil
|
||||
}
|
||||
|
||||
// updateBackgroundImageHandler godoc
|
||||
@@ -180,19 +178,18 @@ func (c *AppImagesController) updateEmailLogoHandler(ctx *gin.Context) {
|
||||
// @Param file formData file true "Background image file"
|
||||
// @Success 204 "No Content"
|
||||
// @Router /api/application-images/background [put]
|
||||
func (c *AppImagesController) updateBackgroundImageHandler(ctx *gin.Context) {
|
||||
file, err := ctx.FormFile("file")
|
||||
func (c *AppImagesController) updateBackgroundImageHandler(ctx *gin.Context) error {
|
||||
file, err := httpserver.FormFile(ctx, "file")
|
||||
if err != nil {
|
||||
_ = ctx.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
if err := c.appImagesService.UpdateImage(ctx.Request.Context(), file, "background"); err != nil {
|
||||
_ = ctx.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
ctx.Status(http.StatusNoContent)
|
||||
return nil
|
||||
}
|
||||
|
||||
// deleteBackgroundImageHandler godoc
|
||||
@@ -201,13 +198,13 @@ func (c *AppImagesController) updateBackgroundImageHandler(ctx *gin.Context) {
|
||||
// @Tags Application Images
|
||||
// @Success 204 "No Content"
|
||||
// @Router /api/application-images/background [delete]
|
||||
func (c *AppImagesController) deleteBackgroundImageHandler(ctx *gin.Context) {
|
||||
func (c *AppImagesController) deleteBackgroundImageHandler(ctx *gin.Context) error {
|
||||
if err := c.appImagesService.DeleteImage(ctx.Request.Context(), "background"); err != nil {
|
||||
_ = ctx.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
ctx.Status(http.StatusNoContent)
|
||||
return nil
|
||||
}
|
||||
|
||||
// updateFaviconHandler godoc
|
||||
@@ -218,39 +215,37 @@ func (c *AppImagesController) deleteBackgroundImageHandler(ctx *gin.Context) {
|
||||
// @Param file formData file true "Favicon file (.svg/.png/.ico)"
|
||||
// @Success 204 "No Content"
|
||||
// @Router /api/application-images/favicon [put]
|
||||
func (c *AppImagesController) updateFaviconHandler(ctx *gin.Context) {
|
||||
file, err := ctx.FormFile("file")
|
||||
func (c *AppImagesController) updateFaviconHandler(ctx *gin.Context) error {
|
||||
file, err := httpserver.FormFile(ctx, "file")
|
||||
if err != nil {
|
||||
_ = ctx.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
fileType := utils.GetFileExtension(file.Filename)
|
||||
mimeType := utils.GetImageMimeType(strings.ToLower(fileType))
|
||||
if !slices.Contains([]string{"image/svg+xml", "image/png", "image/x-icon"}, mimeType) {
|
||||
_ = ctx.Error(&common.WrongFileTypeError{ExpectedFileType: ".svg or .png or .ico"})
|
||||
return
|
||||
return apperror.UnsupportedFileType("SVG, PNG, or ICO")
|
||||
}
|
||||
|
||||
if err := c.appImagesService.UpdateImage(ctx.Request.Context(), file, "favicon"); err != nil {
|
||||
_ = ctx.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
ctx.Status(http.StatusNoContent)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *AppImagesController) getImage(ctx *gin.Context, name string) {
|
||||
func (c *AppImagesController) getImage(ctx *gin.Context, name string) error {
|
||||
reader, size, mimeType, err := c.appImagesService.GetImage(ctx.Request.Context(), name)
|
||||
if err != nil {
|
||||
_ = ctx.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
defer reader.Close()
|
||||
|
||||
ctx.Header("Content-Type", mimeType)
|
||||
utils.SetCacheControlHeader(ctx, 15*time.Minute, 24*time.Hour)
|
||||
ctx.DataFromReader(http.StatusOK, size, mimeType, reader, nil)
|
||||
return nil
|
||||
}
|
||||
|
||||
// updateDefaultProfilePicture godoc
|
||||
@@ -261,19 +256,18 @@ func (c *AppImagesController) getImage(ctx *gin.Context, name string) {
|
||||
// @Param file formData file true "Profile picture image file"
|
||||
// @Success 204 "No Content"
|
||||
// @Router /api/application-images/default-profile-picture [put]
|
||||
func (c *AppImagesController) updateDefaultProfilePicture(ctx *gin.Context) {
|
||||
file, err := ctx.FormFile("file")
|
||||
func (c *AppImagesController) updateDefaultProfilePicture(ctx *gin.Context) error {
|
||||
file, err := httpserver.FormFile(ctx, "file")
|
||||
if err != nil {
|
||||
_ = ctx.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
if err := c.appImagesService.UpdateImage(ctx.Request.Context(), file, "default-profile-picture"); err != nil {
|
||||
_ = ctx.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
ctx.Status(http.StatusNoContent)
|
||||
return nil
|
||||
}
|
||||
|
||||
// deleteDefaultProfilePicture godoc
|
||||
@@ -282,11 +276,11 @@ func (c *AppImagesController) updateDefaultProfilePicture(ctx *gin.Context) {
|
||||
// @Tags Application Images
|
||||
// @Success 204 "No Content"
|
||||
// @Router /api/application-images/default-profile-picture [delete]
|
||||
func (c *AppImagesController) deleteDefaultProfilePicture(ctx *gin.Context) {
|
||||
func (c *AppImagesController) deleteDefaultProfilePicture(ctx *gin.Context) error {
|
||||
if err := c.appImagesService.DeleteImage(ctx.Request.Context(), "default-profile-picture"); err != nil {
|
||||
_ = ctx.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
ctx.Status(http.StatusNoContent)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/pocket-id/pocket-id/backend/internal/dto"
|
||||
"github.com/pocket-id/pocket-id/backend/internal/httpserver"
|
||||
"github.com/pocket-id/pocket-id/backend/internal/middleware"
|
||||
"github.com/pocket-id/pocket-id/backend/internal/utils"
|
||||
|
||||
@@ -20,10 +21,10 @@ func NewAuditLogController(group *gin.RouterGroup, auditLogService *service.Audi
|
||||
auditLogService: auditLogService,
|
||||
}
|
||||
|
||||
group.GET("/audit-logs/all", authMiddleware.Add(), alc.listAllAuditLogsHandler)
|
||||
group.GET("/audit-logs", authMiddleware.WithAdminNotRequired().Add(), alc.listAuditLogsForUserHandler)
|
||||
group.GET("/audit-logs/filters/client-names", authMiddleware.Add(), alc.listClientNamesHandler)
|
||||
group.GET("/audit-logs/filters/users", authMiddleware.Add(), alc.listUserNamesWithIdsHandler)
|
||||
group.GET("/audit-logs/all", authMiddleware.Add(), httpserver.Handle(alc.listAllAuditLogsHandler))
|
||||
group.GET("/audit-logs", authMiddleware.WithAdminNotRequired().Add(), httpserver.Handle(alc.listAuditLogsForUserHandler))
|
||||
group.GET("/audit-logs/filters/client-names", authMiddleware.Add(), httpserver.Handle(alc.listClientNamesHandler))
|
||||
group.GET("/audit-logs/filters/users", authMiddleware.Add(), httpserver.Handle(alc.listUserNamesWithIdsHandler))
|
||||
}
|
||||
|
||||
type AuditLogController struct {
|
||||
@@ -40,7 +41,7 @@ type AuditLogController struct {
|
||||
// @Param sort[direction] query string false "Sort direction (asc or desc)" default("asc")
|
||||
// @Success 200 {object} dto.Paginated[dto.AuditLogDto]
|
||||
// @Router /api/audit-logs [get]
|
||||
func (alc *AuditLogController) listAuditLogsForUserHandler(c *gin.Context) {
|
||||
func (alc *AuditLogController) listAuditLogsForUserHandler(c *gin.Context) error {
|
||||
listRequestOptions := utils.ParseListRequestOptions(c)
|
||||
|
||||
userID := c.GetString("userID")
|
||||
@@ -48,16 +49,14 @@ func (alc *AuditLogController) listAuditLogsForUserHandler(c *gin.Context) {
|
||||
// Fetch audit logs for the user
|
||||
logs, pagination, err := alc.auditLogService.ListAuditLogsForUser(c.Request.Context(), userID, listRequestOptions)
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
// Map the audit logs to DTOs
|
||||
var logsDtos []dto.AuditLogDto
|
||||
err = dto.MapStructList(logs, &logsDtos)
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
// Add device information to the logs
|
||||
@@ -71,6 +70,7 @@ func (alc *AuditLogController) listAuditLogsForUserHandler(c *gin.Context) {
|
||||
Data: logsDtos,
|
||||
Pagination: pagination,
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
// listAllAuditLogsHandler godoc
|
||||
@@ -83,20 +83,18 @@ func (alc *AuditLogController) listAuditLogsForUserHandler(c *gin.Context) {
|
||||
// @Param sort[direction] query string false "Sort direction (asc or desc)" default("asc")
|
||||
// @Success 200 {object} dto.Paginated[dto.AuditLogDto]
|
||||
// @Router /api/audit-logs/all [get]
|
||||
func (alc *AuditLogController) listAllAuditLogsHandler(c *gin.Context) {
|
||||
func (alc *AuditLogController) listAllAuditLogsHandler(c *gin.Context) error {
|
||||
listRequestOptions := utils.ParseListRequestOptions(c)
|
||||
|
||||
logs, pagination, err := alc.auditLogService.ListAllAuditLogs(c.Request.Context(), listRequestOptions)
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
var logsDtos []dto.AuditLogDto
|
||||
err = dto.MapStructList(logs, &logsDtos)
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
for i, logsDto := range logsDtos {
|
||||
@@ -110,6 +108,7 @@ func (alc *AuditLogController) listAllAuditLogsHandler(c *gin.Context) {
|
||||
Data: logsDtos,
|
||||
Pagination: pagination,
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
// listClientNamesHandler godoc
|
||||
@@ -118,14 +117,14 @@ func (alc *AuditLogController) listAllAuditLogsHandler(c *gin.Context) {
|
||||
// @Tags Audit Logs
|
||||
// @Success 200 {array} string "List of client names"
|
||||
// @Router /api/audit-logs/filters/client-names [get]
|
||||
func (alc *AuditLogController) listClientNamesHandler(c *gin.Context) {
|
||||
func (alc *AuditLogController) listClientNamesHandler(c *gin.Context) error {
|
||||
names, err := alc.auditLogService.ListClientNames(c.Request.Context())
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, names)
|
||||
return nil
|
||||
}
|
||||
|
||||
// listUserNamesWithIdsHandler godoc
|
||||
@@ -134,12 +133,12 @@ func (alc *AuditLogController) listClientNamesHandler(c *gin.Context) {
|
||||
// @Tags Audit Logs
|
||||
// @Success 200 {object} map[string]string "Map of user IDs to usernames"
|
||||
// @Router /api/audit-logs/filters/users [get]
|
||||
func (alc *AuditLogController) listUserNamesWithIdsHandler(c *gin.Context) {
|
||||
func (alc *AuditLogController) listUserNamesWithIdsHandler(c *gin.Context) error {
|
||||
users, err := alc.auditLogService.ListUsernamesWithIds(c.Request.Context())
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, users)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/pocket-id/pocket-id/backend/internal/dto"
|
||||
"github.com/pocket-id/pocket-id/backend/internal/httpserver"
|
||||
"github.com/pocket-id/pocket-id/backend/internal/middleware"
|
||||
"github.com/pocket-id/pocket-id/backend/internal/service"
|
||||
)
|
||||
@@ -19,9 +20,9 @@ func NewCustomClaimController(group *gin.RouterGroup, authMiddleware *middleware
|
||||
customClaimsGroup := group.Group("/custom-claims")
|
||||
customClaimsGroup.Use(authMiddleware.Add())
|
||||
{
|
||||
customClaimsGroup.GET("/suggestions", wkc.getSuggestionsHandler)
|
||||
customClaimsGroup.PUT("/user/:userId", wkc.UpdateCustomClaimsForUserHandler)
|
||||
customClaimsGroup.PUT("/user-group/:userGroupId", wkc.UpdateCustomClaimsForUserGroupHandler)
|
||||
customClaimsGroup.GET("/suggestions", httpserver.Handle(wkc.getSuggestionsHandler))
|
||||
customClaimsGroup.PUT("/user/:userId", httpserver.Handle(wkc.UpdateCustomClaimsForUserHandler))
|
||||
customClaimsGroup.PUT("/user-group/:userGroupId", httpserver.Handle(wkc.UpdateCustomClaimsForUserGroupHandler))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,14 +37,14 @@ type CustomClaimController struct {
|
||||
// @Produce json
|
||||
// @Success 200 {array} string "List of suggested custom claim names"
|
||||
// @Router /api/custom-claims/suggestions [get]
|
||||
func (ccc *CustomClaimController) getSuggestionsHandler(c *gin.Context) {
|
||||
func (ccc *CustomClaimController) getSuggestionsHandler(c *gin.Context) error {
|
||||
claims, err := ccc.customClaimService.GetSuggestions(c.Request.Context())
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, claims)
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateCustomClaimsForUserHandler godoc
|
||||
@@ -56,28 +57,26 @@ func (ccc *CustomClaimController) getSuggestionsHandler(c *gin.Context) {
|
||||
// @Param claims body []dto.CustomClaimCreateDto true "List of custom claims to set for the user"
|
||||
// @Success 200 {array} dto.CustomClaimDto "Updated custom claims"
|
||||
// @Router /api/custom-claims/user/{userId} [put]
|
||||
func (ccc *CustomClaimController) UpdateCustomClaimsForUserHandler(c *gin.Context) {
|
||||
func (ccc *CustomClaimController) UpdateCustomClaimsForUserHandler(c *gin.Context) error {
|
||||
var input []dto.CustomClaimCreateDto
|
||||
|
||||
if err := dto.ShouldBindWithNormalizedJSON(c, &input); err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
if err := httpserver.BindJSON(c, &input); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
userId := c.Param("userId")
|
||||
claims, err := ccc.customClaimService.UpdateCustomClaimsForUser(c.Request.Context(), userId, input)
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
var customClaimsDto []dto.CustomClaimDto
|
||||
if err := dto.MapStructList(claims, &customClaimsDto); err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, customClaimsDto)
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateCustomClaimsForUserGroupHandler godoc
|
||||
@@ -90,26 +89,24 @@ func (ccc *CustomClaimController) UpdateCustomClaimsForUserHandler(c *gin.Contex
|
||||
// @Param claims body []dto.CustomClaimCreateDto true "List of custom claims to set for the user group"
|
||||
// @Success 200 {array} dto.CustomClaimDto "Updated custom claims"
|
||||
// @Router /api/custom-claims/user-group/{userGroupId} [put]
|
||||
func (ccc *CustomClaimController) UpdateCustomClaimsForUserGroupHandler(c *gin.Context) {
|
||||
func (ccc *CustomClaimController) UpdateCustomClaimsForUserGroupHandler(c *gin.Context) error {
|
||||
var input []dto.CustomClaimCreateDto
|
||||
|
||||
if err := dto.ShouldBindWithNormalizedJSON(c, &input); err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
if err := httpserver.BindJSON(c, &input); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
userGroupId := c.Param("userGroupId")
|
||||
claims, err := ccc.customClaimService.UpdateCustomClaimsForUserGroup(c.Request.Context(), userGroupId, input)
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
var customClaimsDto []dto.CustomClaimDto
|
||||
if err := dto.MapStructList(claims, &customClaimsDto); err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, customClaimsDto)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -7,25 +7,26 @@ import (
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"github.com/pocket-id/pocket-id/backend/internal/httpserver"
|
||||
"github.com/pocket-id/pocket-id/backend/internal/service"
|
||||
)
|
||||
|
||||
func NewTestController(group *gin.RouterGroup, testService *service.TestService) {
|
||||
testController := &TestController{TestService: testService}
|
||||
|
||||
group.POST("/test/reset", testController.resetAndSeedHandler)
|
||||
group.POST("/test/accesstoken", testController.signAccessToken)
|
||||
group.POST("/test/refreshtoken", testController.signRefreshToken)
|
||||
group.POST("/test/reset", httpserver.Handle(testController.resetAndSeedHandler))
|
||||
group.POST("/test/accesstoken", httpserver.Handle(testController.signAccessToken))
|
||||
group.POST("/test/refreshtoken", httpserver.Handle(testController.signRefreshToken))
|
||||
|
||||
group.GET("/externalidp/jwks.json", testController.externalIdPJWKS)
|
||||
group.POST("/externalidp/sign", testController.externalIdPSignToken)
|
||||
group.GET("/externalidp/jwks.json", httpserver.Handle(testController.externalIdPJWKS))
|
||||
group.POST("/externalidp/sign", httpserver.Handle(testController.externalIdPSignToken))
|
||||
}
|
||||
|
||||
type TestController struct {
|
||||
TestService *service.TestService
|
||||
}
|
||||
|
||||
func (tc *TestController) resetAndSeedHandler(c *gin.Context) {
|
||||
func (tc *TestController) resetAndSeedHandler(c *gin.Context) error {
|
||||
var baseURL string
|
||||
if c.Request.TLS != nil {
|
||||
baseURL = "https://" + c.Request.Host
|
||||
@@ -37,111 +38,103 @@ func (tc *TestController) resetAndSeedHandler(c *gin.Context) {
|
||||
skipSeed := c.Query("skip-seed") == "true"
|
||||
|
||||
if err := tc.TestService.ResetDatabase(); err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
if err := tc.TestService.ResetApplicationImages(c.Request.Context()); err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
if !skipSeed {
|
||||
if err := tc.TestService.SeedDatabase(baseURL); err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := tc.TestService.ResetAppConfig(c.Request.Context()); err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
if !skipLdap {
|
||||
if err := tc.TestService.SetLdapTestConfig(c.Request.Context()); err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
if err := tc.TestService.SyncLdap(c.Request.Context()); err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
c.Status(http.StatusNoContent)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (tc *TestController) externalIdPJWKS(c *gin.Context) {
|
||||
func (tc *TestController) externalIdPJWKS(c *gin.Context) error {
|
||||
jwks, err := tc.TestService.GetExternalIdPJWKS()
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, jwks)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (tc *TestController) externalIdPSignToken(c *gin.Context) {
|
||||
func (tc *TestController) externalIdPSignToken(c *gin.Context) error {
|
||||
var input struct {
|
||||
Aud string `json:"aud"`
|
||||
Iss string `json:"iss"`
|
||||
Sub string `json:"sub"`
|
||||
}
|
||||
err := c.ShouldBindJSON(&input)
|
||||
err := httpserver.BindJSON(c, &input)
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
token, err := tc.TestService.SignExternalIdPToken(input.Iss, input.Sub, input.Aud)
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
c.Writer.WriteString(token)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (tc *TestController) signAccessToken(c *gin.Context) {
|
||||
func (tc *TestController) signAccessToken(c *gin.Context) error {
|
||||
var input struct {
|
||||
UserID string `json:"user"`
|
||||
ClientID string `json:"client"`
|
||||
Expired bool `json:"expired"`
|
||||
}
|
||||
err := c.ShouldBindJSON(&input)
|
||||
err := httpserver.BindJSON(c, &input)
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
token, err := tc.TestService.SignAccessToken(c.Request.Context(), input.UserID, input.ClientID, input.Expired)
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
c.Writer.WriteString(token)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (tc *TestController) signRefreshToken(c *gin.Context) {
|
||||
func (tc *TestController) signRefreshToken(c *gin.Context) error {
|
||||
var input struct {
|
||||
UserID string `json:"user"`
|
||||
ClientID string `json:"client"`
|
||||
RefreshToken string `json:"rt"`
|
||||
}
|
||||
err := c.ShouldBindJSON(&input)
|
||||
err := httpserver.BindJSON(c, &input)
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
token, err := tc.TestService.SignRefreshToken(c.Request.Context(), input.UserID, input.ClientID, input.RefreshToken)
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
c.Writer.WriteString(token)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -10,8 +8,9 @@ import (
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"github.com/pocket-id/pocket-id/backend/internal/common"
|
||||
"github.com/pocket-id/pocket-id/backend/internal/apperror"
|
||||
"github.com/pocket-id/pocket-id/backend/internal/dto"
|
||||
"github.com/pocket-id/pocket-id/backend/internal/httpserver"
|
||||
"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/utils"
|
||||
@@ -26,31 +25,31 @@ func NewOidcController(group *gin.RouterGroup, authMiddleware *middleware.AuthMi
|
||||
oidcService: oidcService,
|
||||
}
|
||||
|
||||
group.GET("/oidc/clients", authMiddleware.Add(), oc.listClientsHandler)
|
||||
group.POST("/oidc/clients", authMiddleware.Add(), oc.createClientHandler)
|
||||
group.GET("/oidc/clients/:id", authMiddleware.Add(), oc.getClientHandler)
|
||||
group.GET("/oidc/clients/:id/meta", oc.getClientMetaDataHandler)
|
||||
group.PUT("/oidc/clients/:id", authMiddleware.Add(), oc.updateClientHandler)
|
||||
group.POST("/oidc/clients/:id/refresh", authMiddleware.Add(), oc.refreshClientMetadataHandler)
|
||||
group.DELETE("/oidc/clients/:id", authMiddleware.Add(), oc.deleteClientHandler)
|
||||
group.GET("/oidc/clients", authMiddleware.Add(), httpserver.Handle(oc.listClientsHandler))
|
||||
group.POST("/oidc/clients", authMiddleware.Add(), httpserver.Handle(oc.createClientHandler))
|
||||
group.GET("/oidc/clients/:id", authMiddleware.Add(), httpserver.Handle(oc.getClientHandler))
|
||||
group.GET("/oidc/clients/:id/meta", httpserver.Handle(oc.getClientMetaDataHandler))
|
||||
group.PUT("/oidc/clients/:id", authMiddleware.Add(), httpserver.Handle(oc.updateClientHandler))
|
||||
group.POST("/oidc/clients/:id/refresh", authMiddleware.Add(), httpserver.Handle(oc.refreshClientMetadataHandler))
|
||||
group.DELETE("/oidc/clients/:id", authMiddleware.Add(), httpserver.Handle(oc.deleteClientHandler))
|
||||
|
||||
group.PUT("/oidc/clients/:id/allowed-user-groups", authMiddleware.Add(), oc.updateAllowedUserGroupsHandler)
|
||||
group.POST("/oidc/clients/:id/secret", authMiddleware.Add(), oc.createClientSecretHandler)
|
||||
group.PUT("/oidc/clients/:id/allowed-user-groups", authMiddleware.Add(), httpserver.Handle(oc.updateAllowedUserGroupsHandler))
|
||||
group.POST("/oidc/clients/:id/secret", authMiddleware.Add(), httpserver.Handle(oc.createClientSecretHandler))
|
||||
|
||||
group.GET("/oidc/clients/:id/logo", oc.getClientLogoHandler)
|
||||
group.DELETE("/oidc/clients/:id/logo", authMiddleware.Add(), oc.deleteClientLogoHandler)
|
||||
group.POST("/oidc/clients/:id/logo", authMiddleware.Add(), fileSizeLimitMiddleware.Add(2<<20), oc.updateClientLogoHandler)
|
||||
group.GET("/oidc/clients/:id/logo", httpserver.Handle(oc.getClientLogoHandler))
|
||||
group.DELETE("/oidc/clients/:id/logo", authMiddleware.Add(), httpserver.Handle(oc.deleteClientLogoHandler))
|
||||
group.POST("/oidc/clients/:id/logo", authMiddleware.Add(), fileSizeLimitMiddleware.Add(2<<20), httpserver.Handle(oc.updateClientLogoHandler))
|
||||
|
||||
group.GET("/oidc/clients/:id/preview/:userId", authMiddleware.Add(), oc.getClientPreviewHandler)
|
||||
group.GET("/oidc/clients/:id/preview/:userId", authMiddleware.Add(), httpserver.Handle(oc.getClientPreviewHandler))
|
||||
|
||||
group.GET("/oidc/users/me/authorized-clients", authMiddleware.WithAdminNotRequired().Add(), oc.listOwnAuthorizedClientsHandler)
|
||||
group.GET("/oidc/users/:id/authorized-clients", authMiddleware.Add(), oc.listAuthorizedClientsHandler)
|
||||
group.GET("/oidc/users/me/authorized-clients", authMiddleware.WithAdminNotRequired().Add(), httpserver.Handle(oc.listOwnAuthorizedClientsHandler))
|
||||
group.GET("/oidc/users/:id/authorized-clients", authMiddleware.Add(), httpserver.Handle(oc.listAuthorizedClientsHandler))
|
||||
|
||||
group.DELETE("/oidc/users/me/authorized-clients/:clientId", authMiddleware.WithAdminNotRequired().Add(), oc.revokeOwnClientAuthorizationHandler)
|
||||
group.DELETE("/oidc/users/me/authorized-clients/:clientId", authMiddleware.WithAdminNotRequired().Add(), httpserver.Handle(oc.revokeOwnClientAuthorizationHandler))
|
||||
|
||||
group.GET("/oidc/users/me/clients", authMiddleware.WithAdminNotRequired().Add(), oc.listOwnAccessibleClientsHandler)
|
||||
group.GET("/oidc/users/me/clients", authMiddleware.WithAdminNotRequired().Add(), httpserver.Handle(oc.listOwnAccessibleClientsHandler))
|
||||
|
||||
group.GET("/oidc/clients/:id/scim-service-provider", authMiddleware.Add(), oc.getClientScimServiceProviderHandler)
|
||||
group.GET("/oidc/clients/:id/scim-service-provider", authMiddleware.Add(), httpserver.Handle(oc.getClientScimServiceProviderHandler))
|
||||
|
||||
}
|
||||
|
||||
@@ -66,22 +65,21 @@ type OidcController struct {
|
||||
// @Param id path string true "Client ID"
|
||||
// @Success 200 {object} dto.OidcClientMetaDataDto "Client metadata"
|
||||
// @Router /api/oidc/clients/{id}/meta [get]
|
||||
func (oc *OidcController) getClientMetaDataHandler(c *gin.Context) {
|
||||
func (oc *OidcController) getClientMetaDataHandler(c *gin.Context) error {
|
||||
clientId := c.Param("id")
|
||||
client, err := oc.oidcService.GetClient(c.Request.Context(), clientId)
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
clientDto := dto.OidcClientMetaDataDto{}
|
||||
err = dto.MapStruct(client, &clientDto)
|
||||
if err == nil {
|
||||
c.JSON(http.StatusOK, clientDto)
|
||||
return
|
||||
if err := dto.MapStruct(client, &clientDto); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_ = c.Error(err)
|
||||
clientDto.HasDarkLogo = client.HasDarkLogo()
|
||||
c.JSON(http.StatusOK, clientDto)
|
||||
return nil
|
||||
}
|
||||
|
||||
// getClientHandler godoc
|
||||
@@ -92,22 +90,21 @@ func (oc *OidcController) getClientMetaDataHandler(c *gin.Context) {
|
||||
// @Param id path string true "Client ID"
|
||||
// @Success 200 {object} dto.OidcClientWithAllowedUserGroupsDto "Client information"
|
||||
// @Router /api/oidc/clients/{id} [get]
|
||||
func (oc *OidcController) getClientHandler(c *gin.Context) {
|
||||
func (oc *OidcController) getClientHandler(c *gin.Context) error {
|
||||
clientId := c.Param("id")
|
||||
client, err := oc.oidcService.GetClient(c.Request.Context(), clientId)
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
clientDto := dto.OidcClientWithAllowedUserGroupsDto{}
|
||||
err = dto.MapStruct(client, &clientDto)
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, clientDto)
|
||||
return nil
|
||||
}
|
||||
|
||||
// listClientsHandler godoc
|
||||
@@ -121,14 +118,13 @@ func (oc *OidcController) getClientHandler(c *gin.Context) {
|
||||
// @Param sort[direction] query string false "Sort direction (asc or desc)" default("asc")
|
||||
// @Success 200 {object} dto.Paginated[dto.OidcClientWithAllowedGroupsCountDto]
|
||||
// @Router /api/oidc/clients [get]
|
||||
func (oc *OidcController) listClientsHandler(c *gin.Context) {
|
||||
func (oc *OidcController) listClientsHandler(c *gin.Context) error {
|
||||
searchTerm := c.Query("search")
|
||||
listRequestOptions := utils.ParseListRequestOptions(c)
|
||||
|
||||
clients, pagination, err := oc.oidcService.ListClients(c.Request.Context(), searchTerm, listRequestOptions)
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
// Map the user groups to DTOs
|
||||
@@ -136,14 +132,13 @@ func (oc *OidcController) listClientsHandler(c *gin.Context) {
|
||||
for i, client := range clients {
|
||||
var clientDto dto.OidcClientWithAllowedGroupsCountDto
|
||||
if err := dto.MapStruct(client, &clientDto); err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
clientDto.HasDarkLogo = client.HasDarkLogo()
|
||||
|
||||
clientDto.AllowedUserGroupsCount, err = oc.oidcService.GetAllowedGroupsCountOfClient(c, client.ID)
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
clientsDto[i] = clientDto
|
||||
}
|
||||
@@ -152,6 +147,7 @@ func (oc *OidcController) listClientsHandler(c *gin.Context) {
|
||||
Data: clientsDto,
|
||||
Pagination: pagination,
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
// createClientHandler godoc
|
||||
@@ -163,26 +159,24 @@ func (oc *OidcController) listClientsHandler(c *gin.Context) {
|
||||
// @Param client body dto.OidcClientCreateDto true "Client information"
|
||||
// @Success 201 {object} dto.OidcClientWithAllowedUserGroupsDto "Created client"
|
||||
// @Router /api/oidc/clients [post]
|
||||
func (oc *OidcController) createClientHandler(c *gin.Context) {
|
||||
func (oc *OidcController) createClientHandler(c *gin.Context) error {
|
||||
var input dto.OidcClientCreateDto
|
||||
if err := c.ShouldBindJSON(&input); err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
if err := httpserver.BindJSON(c, &input); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
client, err := oc.oidcService.CreateClient(c.Request.Context(), input, c.GetString("userID"))
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
var clientDto dto.OidcClientWithAllowedUserGroupsDto
|
||||
if err := dto.MapStruct(client, &clientDto); err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
c.JSON(http.StatusCreated, clientDto)
|
||||
return nil
|
||||
}
|
||||
|
||||
// deleteClientHandler godoc
|
||||
@@ -192,14 +186,14 @@ func (oc *OidcController) createClientHandler(c *gin.Context) {
|
||||
// @Param id path string true "Client ID"
|
||||
// @Success 204 "No Content"
|
||||
// @Router /api/oidc/clients/{id} [delete]
|
||||
func (oc *OidcController) deleteClientHandler(c *gin.Context) {
|
||||
func (oc *OidcController) deleteClientHandler(c *gin.Context) error {
|
||||
err := oc.oidcService.DeleteClient(c.Request.Context(), c.Param("id"))
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
c.Status(http.StatusNoContent)
|
||||
return nil
|
||||
}
|
||||
|
||||
// updateClientHandler godoc
|
||||
@@ -212,26 +206,24 @@ func (oc *OidcController) deleteClientHandler(c *gin.Context) {
|
||||
// @Param client body dto.OidcClientUpdateDto true "Client information"
|
||||
// @Success 200 {object} dto.OidcClientWithAllowedUserGroupsDto "Updated client"
|
||||
// @Router /api/oidc/clients/{id} [put]
|
||||
func (oc *OidcController) updateClientHandler(c *gin.Context) {
|
||||
func (oc *OidcController) updateClientHandler(c *gin.Context) error {
|
||||
var input dto.OidcClientUpdateDto
|
||||
if err := c.ShouldBindJSON(&input); err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
if err := httpserver.BindJSON(c, &input); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
client, err := oc.oidcService.UpdateClient(c.Request.Context(), c.Param("id"), input)
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
var clientDto dto.OidcClientWithAllowedUserGroupsDto
|
||||
if err := dto.MapStruct(client, &clientDto); err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, clientDto)
|
||||
return nil
|
||||
}
|
||||
|
||||
// refreshClientMetadataHandler godoc
|
||||
@@ -242,20 +234,20 @@ func (oc *OidcController) updateClientHandler(c *gin.Context) {
|
||||
// @Param id path string true "Client ID"
|
||||
// @Success 200 {object} dto.OidcClientWithAllowedUserGroupsDto "Refreshed client"
|
||||
// @Router /api/oidc/clients/{id}/refresh [post]
|
||||
func (oc *OidcController) refreshClientMetadataHandler(c *gin.Context) {
|
||||
func (oc *OidcController) refreshClientMetadataHandler(c *gin.Context) error {
|
||||
client, err := oc.oidcService.RefreshClientMetadata(c.Request.Context(), c.Param("id"))
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
var clientDto dto.OidcClientWithAllowedUserGroupsDto
|
||||
if err := dto.MapStruct(client, &clientDto); err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
clientDto.HasDarkLogo = client.HasDarkLogo()
|
||||
c.JSON(http.StatusOK, clientDto)
|
||||
return nil
|
||||
}
|
||||
|
||||
// createClientSecretHandler godoc
|
||||
@@ -268,20 +260,19 @@ func (oc *OidcController) refreshClientMetadataHandler(c *gin.Context) {
|
||||
// @Param payload body dto.OidcClientSecretDto false "Client secret"
|
||||
// @Success 200 {object} object "{ \"secret\": \"string\" }"
|
||||
// @Router /api/oidc/clients/{id}/secret [post]
|
||||
func (oc *OidcController) createClientSecretHandler(c *gin.Context) {
|
||||
func (oc *OidcController) createClientSecretHandler(c *gin.Context) error {
|
||||
var input dto.OidcClientSecretDto
|
||||
if err := c.ShouldBindJSON(&input); err != nil && !errors.Is(err, io.EOF) {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
if err := httpserver.BindOptionalJSON(c, &input); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
secret, err := oc.oidcService.CreateClientSecret(c.Request.Context(), c.Param("id"), input)
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"secret": secret})
|
||||
return nil
|
||||
}
|
||||
|
||||
// getClientLogoHandler godoc
|
||||
@@ -295,13 +286,12 @@ func (oc *OidcController) createClientSecretHandler(c *gin.Context) {
|
||||
// @Param light query boolean false "Light mode logo (true) or dark mode logo (false)"
|
||||
// @Success 200 {file} binary "Logo image"
|
||||
// @Router /api/oidc/clients/{id}/logo [get]
|
||||
func (oc *OidcController) getClientLogoHandler(c *gin.Context) {
|
||||
func (oc *OidcController) getClientLogoHandler(c *gin.Context) error {
|
||||
lightLogo, _ := strconv.ParseBool(c.DefaultQuery("light", "true"))
|
||||
|
||||
reader, size, mimeType, err := oc.oidcService.GetClientLogo(c.Request.Context(), c.Param("id"), lightLogo)
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
defer reader.Close()
|
||||
|
||||
@@ -309,6 +299,7 @@ func (oc *OidcController) getClientLogoHandler(c *gin.Context) {
|
||||
|
||||
c.Header("Content-Type", mimeType)
|
||||
c.DataFromReader(http.StatusOK, size, mimeType, reader, nil)
|
||||
return nil
|
||||
}
|
||||
|
||||
// updateClientLogoHandler godoc
|
||||
@@ -321,22 +312,21 @@ func (oc *OidcController) getClientLogoHandler(c *gin.Context) {
|
||||
// @Param light query boolean false "Light mode logo (true) or dark mode logo (false)"
|
||||
// @Success 204 "No Content"
|
||||
// @Router /api/oidc/clients/{id}/logo [post]
|
||||
func (oc *OidcController) updateClientLogoHandler(c *gin.Context) {
|
||||
file, err := c.FormFile("file")
|
||||
func (oc *OidcController) updateClientLogoHandler(c *gin.Context) error {
|
||||
file, err := httpserver.FormFile(c, "file")
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
lightLogo, _ := strconv.ParseBool(c.DefaultQuery("light", "true"))
|
||||
|
||||
err = oc.oidcService.UpdateClientLogo(c.Request.Context(), c.Param("id"), file, lightLogo)
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
c.Status(http.StatusNoContent)
|
||||
return nil
|
||||
}
|
||||
|
||||
// deleteClientLogoHandler godoc
|
||||
@@ -347,7 +337,7 @@ func (oc *OidcController) updateClientLogoHandler(c *gin.Context) {
|
||||
// @Param light query boolean false "Light mode logo (true) or dark mode logo (false)"
|
||||
// @Success 204 "No Content"
|
||||
// @Router /api/oidc/clients/{id}/logo [delete]
|
||||
func (oc *OidcController) deleteClientLogoHandler(c *gin.Context) {
|
||||
func (oc *OidcController) deleteClientLogoHandler(c *gin.Context) error {
|
||||
var err error
|
||||
|
||||
lightLogo, _ := strconv.ParseBool(c.DefaultQuery("light", "true"))
|
||||
@@ -358,11 +348,11 @@ func (oc *OidcController) deleteClientLogoHandler(c *gin.Context) {
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
c.Status(http.StatusNoContent)
|
||||
return nil
|
||||
}
|
||||
|
||||
// updateAllowedUserGroupsHandler godoc
|
||||
@@ -375,27 +365,25 @@ func (oc *OidcController) deleteClientLogoHandler(c *gin.Context) {
|
||||
// @Param groups body dto.OidcUpdateAllowedUserGroupsDto true "User group IDs"
|
||||
// @Success 200 {object} dto.OidcClientDto "Updated client"
|
||||
// @Router /api/oidc/clients/{id}/allowed-user-groups [put]
|
||||
func (oc *OidcController) updateAllowedUserGroupsHandler(c *gin.Context) {
|
||||
func (oc *OidcController) updateAllowedUserGroupsHandler(c *gin.Context) error {
|
||||
var input dto.OidcUpdateAllowedUserGroupsDto
|
||||
if err := c.ShouldBindJSON(&input); err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
if err := httpserver.BindJSON(c, &input); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
oidcClient, err := oc.oidcService.UpdateAllowedUserGroups(c.Request.Context(), c.Param("id"), input)
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
var oidcClientDto dto.OidcClientDto
|
||||
if err := dto.MapStruct(oidcClient, &oidcClientDto); err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
oidcClientDto.HasDarkLogo = oidcClient.HasDarkLogo()
|
||||
|
||||
c.JSON(http.StatusOK, oidcClientDto)
|
||||
return nil
|
||||
}
|
||||
|
||||
// listOwnAuthorizedClientsHandler godoc
|
||||
@@ -408,9 +396,9 @@ func (oc *OidcController) updateAllowedUserGroupsHandler(c *gin.Context) {
|
||||
// @Param sort[direction] query string false "Sort direction (asc or desc)" default("asc")
|
||||
// @Success 200 {object} dto.Paginated[dto.AuthorizedOidcClientDto]
|
||||
// @Router /api/oidc/users/me/authorized-clients [get]
|
||||
func (oc *OidcController) listOwnAuthorizedClientsHandler(c *gin.Context) {
|
||||
func (oc *OidcController) listOwnAuthorizedClientsHandler(c *gin.Context) error {
|
||||
userID := c.GetString("userID")
|
||||
oc.listAuthorizedClients(c, userID)
|
||||
return oc.listAuthorizedClients(c, userID)
|
||||
}
|
||||
|
||||
// listAuthorizedClientsHandler godoc
|
||||
@@ -424,31 +412,30 @@ func (oc *OidcController) listOwnAuthorizedClientsHandler(c *gin.Context) {
|
||||
// @Param sort[direction] query string false "Sort direction (asc or desc)" default("asc")
|
||||
// @Success 200 {object} dto.Paginated[dto.AuthorizedOidcClientDto]
|
||||
// @Router /api/oidc/users/{id}/authorized-clients [get]
|
||||
func (oc *OidcController) listAuthorizedClientsHandler(c *gin.Context) {
|
||||
func (oc *OidcController) listAuthorizedClientsHandler(c *gin.Context) error {
|
||||
userID := c.Param("id")
|
||||
oc.listAuthorizedClients(c, userID)
|
||||
return oc.listAuthorizedClients(c, userID)
|
||||
}
|
||||
|
||||
func (oc *OidcController) listAuthorizedClients(c *gin.Context, userID string) {
|
||||
func (oc *OidcController) listAuthorizedClients(c *gin.Context, userID string) error {
|
||||
listRequestOptions := utils.ParseListRequestOptions(c)
|
||||
|
||||
authorizedClients, pagination, err := oc.oidcService.ListAuthorizedClients(c.Request.Context(), userID, listRequestOptions)
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
// Map the clients to DTOs
|
||||
var authorizedClientsDto []dto.AuthorizedOidcClientDto
|
||||
if err := dto.MapStructList(authorizedClients, &authorizedClientsDto); err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, dto.Paginated[dto.AuthorizedOidcClientDto]{
|
||||
Data: authorizedClientsDto,
|
||||
Pagination: pagination,
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
// revokeOwnClientAuthorizationHandler godoc
|
||||
@@ -458,18 +445,18 @@ func (oc *OidcController) listAuthorizedClients(c *gin.Context, userID string) {
|
||||
// @Param clientId path string true "Client ID to revoke authorization for"
|
||||
// @Success 204 "No Content"
|
||||
// @Router /api/oidc/users/me/authorized-clients/{clientId} [delete]
|
||||
func (oc *OidcController) revokeOwnClientAuthorizationHandler(c *gin.Context) {
|
||||
func (oc *OidcController) revokeOwnClientAuthorizationHandler(c *gin.Context) error {
|
||||
clientID := c.Param("clientId")
|
||||
|
||||
userID := c.GetString("userID")
|
||||
|
||||
err := oc.oidcService.RevokeAuthorizedClient(c.Request.Context(), userID, clientID)
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
c.Status(http.StatusNoContent)
|
||||
return nil
|
||||
}
|
||||
|
||||
// listOwnAccessibleClientsHandler godoc
|
||||
@@ -482,21 +469,21 @@ func (oc *OidcController) revokeOwnClientAuthorizationHandler(c *gin.Context) {
|
||||
// @Param sort[direction] query string false "Sort direction (asc or desc)" default("asc")
|
||||
// @Success 200 {object} dto.Paginated[dto.AccessibleOidcClientDto]
|
||||
// @Router /api/oidc/users/me/clients [get]
|
||||
func (oc *OidcController) listOwnAccessibleClientsHandler(c *gin.Context) {
|
||||
func (oc *OidcController) listOwnAccessibleClientsHandler(c *gin.Context) error {
|
||||
listRequestOptions := utils.ParseListRequestOptions(c)
|
||||
|
||||
userID := c.GetString("userID")
|
||||
|
||||
clients, pagination, err := oc.oidcService.ListAccessibleOidcClients(c.Request.Context(), userID, listRequestOptions)
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, dto.Paginated[dto.AccessibleOidcClientDto]{
|
||||
Data: clients,
|
||||
Pagination: pagination,
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
// getClientPreviewHandler godoc
|
||||
@@ -510,24 +497,21 @@ func (oc *OidcController) listOwnAccessibleClientsHandler(c *gin.Context) {
|
||||
// @Success 200 {object} dto.OidcClientPreviewDto "Preview data including ID token, access token, and userinfo payloads"
|
||||
// @Security BearerAuth
|
||||
// @Router /api/oidc/clients/{id}/preview/{userId} [get]
|
||||
func (oc *OidcController) getClientPreviewHandler(c *gin.Context) {
|
||||
func (oc *OidcController) getClientPreviewHandler(c *gin.Context) error {
|
||||
clientID := c.Param("id")
|
||||
userID := c.Param("userId")
|
||||
scopes := c.Query("scopes")
|
||||
|
||||
if clientID == "" {
|
||||
_ = c.Error(&common.ValidationError{Message: "client ID is required"})
|
||||
return
|
||||
return apperror.MissingField("clientId")
|
||||
}
|
||||
|
||||
if userID == "" {
|
||||
_ = c.Error(&common.ValidationError{Message: "user ID is required"})
|
||||
return
|
||||
return apperror.MissingField("userId")
|
||||
}
|
||||
|
||||
if scopes == "" {
|
||||
_ = c.Error(&common.ValidationError{Message: "scopes are required"})
|
||||
return
|
||||
return apperror.MissingField("scopes")
|
||||
}
|
||||
|
||||
preview, err := oc.oidcService.GetClientPreview(
|
||||
@@ -538,11 +522,11 @@ func (oc *OidcController) getClientPreviewHandler(c *gin.Context) {
|
||||
c.GetString("authenticationMethod"))
|
||||
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, preview)
|
||||
return nil
|
||||
}
|
||||
|
||||
// getClientScimServiceProviderHandler godoc
|
||||
@@ -553,20 +537,19 @@ func (oc *OidcController) getClientPreviewHandler(c *gin.Context) {
|
||||
// @Param id path string true "Client ID"
|
||||
// @Success 200 {object} dto.ScimServiceProviderDTO "SCIM service provider configuration"
|
||||
// @Router /api/oidc/clients/{id}/scim-service-provider [get]
|
||||
func (oc *OidcController) getClientScimServiceProviderHandler(c *gin.Context) {
|
||||
func (oc *OidcController) getClientScimServiceProviderHandler(c *gin.Context) error {
|
||||
clientID := c.Param("id")
|
||||
|
||||
provider, err := oc.oidcService.GetClientScimServiceProvider(c.Request.Context(), clientID)
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
var providerDto dto.ScimServiceProviderDTO
|
||||
if err := dto.MapStruct(provider, &providerDto); err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, providerDto)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/pocket-id/pocket-id/backend/internal/dto"
|
||||
"github.com/pocket-id/pocket-id/backend/internal/httpserver"
|
||||
"github.com/pocket-id/pocket-id/backend/internal/middleware"
|
||||
"github.com/pocket-id/pocket-id/backend/internal/service"
|
||||
)
|
||||
@@ -14,10 +15,10 @@ func NewScimController(group *gin.RouterGroup, authMiddleware *middleware.AuthMi
|
||||
scimService: scimService,
|
||||
}
|
||||
|
||||
group.POST("/scim/service-provider", authMiddleware.Add(), ugc.createServiceProviderHandler)
|
||||
group.POST("/scim/service-provider/:id/sync", authMiddleware.Add(), ugc.syncServiceProviderHandler)
|
||||
group.PUT("/scim/service-provider/:id", authMiddleware.Add(), ugc.updateServiceProviderHandler)
|
||||
group.DELETE("/scim/service-provider/:id", authMiddleware.Add(), ugc.deleteServiceProviderHandler)
|
||||
group.POST("/scim/service-provider", authMiddleware.Add(), httpserver.Handle(ugc.createServiceProviderHandler))
|
||||
group.POST("/scim/service-provider/:id/sync", authMiddleware.Add(), httpserver.Handle(ugc.syncServiceProviderHandler))
|
||||
group.PUT("/scim/service-provider/:id", authMiddleware.Add(), httpserver.Handle(ugc.updateServiceProviderHandler))
|
||||
group.DELETE("/scim/service-provider/:id", authMiddleware.Add(), httpserver.Handle(ugc.deleteServiceProviderHandler))
|
||||
}
|
||||
|
||||
type ScimController struct {
|
||||
@@ -31,14 +32,14 @@ type ScimController struct {
|
||||
// @Param id path string true "Service Provider ID"
|
||||
// @Success 200 "OK"
|
||||
// @Router /api/scim/service-provider/{id}/sync [post]
|
||||
func (c *ScimController) syncServiceProviderHandler(ctx *gin.Context) {
|
||||
func (c *ScimController) syncServiceProviderHandler(ctx *gin.Context) error {
|
||||
err := c.scimService.SyncServiceProvider(ctx.Request.Context(), ctx.Param("id"))
|
||||
if err != nil {
|
||||
_ = ctx.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
ctx.Status(http.StatusOK)
|
||||
return nil
|
||||
}
|
||||
|
||||
// createServiceProviderHandler godoc
|
||||
@@ -50,26 +51,24 @@ func (c *ScimController) syncServiceProviderHandler(ctx *gin.Context) {
|
||||
// @Param serviceProvider body dto.ScimServiceProviderCreateDTO true "SCIM service provider information"
|
||||
// @Success 201 {object} dto.ScimServiceProviderDTO "Created SCIM service provider"
|
||||
// @Router /api/scim/service-provider [post]
|
||||
func (c *ScimController) createServiceProviderHandler(ctx *gin.Context) {
|
||||
func (c *ScimController) createServiceProviderHandler(ctx *gin.Context) error {
|
||||
var input dto.ScimServiceProviderCreateDTO
|
||||
if err := ctx.ShouldBindJSON(&input); err != nil {
|
||||
_ = ctx.Error(err)
|
||||
return
|
||||
if err := httpserver.BindJSON(ctx, &input); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
provider, err := c.scimService.CreateServiceProvider(ctx.Request.Context(), &input)
|
||||
if err != nil {
|
||||
_ = ctx.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
var providerDTO dto.ScimServiceProviderDTO
|
||||
if err := dto.MapStruct(provider, &providerDTO); err != nil {
|
||||
_ = ctx.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
ctx.JSON(http.StatusCreated, providerDTO)
|
||||
return nil
|
||||
}
|
||||
|
||||
// updateServiceProviderHandler godoc
|
||||
@@ -82,26 +81,24 @@ func (c *ScimController) createServiceProviderHandler(ctx *gin.Context) {
|
||||
// @Param serviceProvider body dto.ScimServiceProviderCreateDTO true "SCIM service provider information"
|
||||
// @Success 200 {object} dto.ScimServiceProviderDTO "Updated SCIM service provider"
|
||||
// @Router /api/scim/service-provider/{id} [put]
|
||||
func (c *ScimController) updateServiceProviderHandler(ctx *gin.Context) {
|
||||
func (c *ScimController) updateServiceProviderHandler(ctx *gin.Context) error {
|
||||
var input dto.ScimServiceProviderCreateDTO
|
||||
if err := ctx.ShouldBindJSON(&input); err != nil {
|
||||
_ = ctx.Error(err)
|
||||
return
|
||||
if err := httpserver.BindJSON(ctx, &input); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
provider, err := c.scimService.UpdateServiceProvider(ctx.Request.Context(), ctx.Param("id"), &input)
|
||||
if err != nil {
|
||||
_ = ctx.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
var providerDTO dto.ScimServiceProviderDTO
|
||||
if err := dto.MapStruct(provider, &providerDTO); err != nil {
|
||||
_ = ctx.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
ctx.JSON(http.StatusOK, providerDTO)
|
||||
return nil
|
||||
}
|
||||
|
||||
// deleteServiceProviderHandler godoc
|
||||
@@ -111,12 +108,12 @@ func (c *ScimController) updateServiceProviderHandler(ctx *gin.Context) {
|
||||
// @Param id path string true "Service Provider ID"
|
||||
// @Success 204 "No Content"
|
||||
// @Router /api/scim/service-provider/{id} [delete]
|
||||
func (c *ScimController) deleteServiceProviderHandler(ctx *gin.Context) {
|
||||
func (c *ScimController) deleteServiceProviderHandler(ctx *gin.Context) error {
|
||||
err := c.scimService.DeleteServiceProvider(ctx.Request.Context(), ctx.Param("id"))
|
||||
if err != nil {
|
||||
_ = ctx.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
ctx.Status(http.StatusNoContent)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/pocket-id/pocket-id/backend/internal/dto"
|
||||
"github.com/pocket-id/pocket-id/backend/internal/httpserver"
|
||||
"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/utils"
|
||||
@@ -26,26 +27,26 @@ func NewUserController(group *gin.RouterGroup, authMiddleware *middleware.AuthMi
|
||||
webAuthnService: webAuthnService,
|
||||
}
|
||||
|
||||
group.GET("/users", authMiddleware.Add(), uc.listUsersHandler)
|
||||
group.GET("/users/me", authMiddleware.WithAdminNotRequired().Add(), uc.getCurrentUserHandler)
|
||||
group.GET("/users/:id", authMiddleware.Add(), uc.getUserHandler)
|
||||
group.POST("/users", authMiddleware.Add(), uc.createUserHandler)
|
||||
group.PUT("/users/:id", authMiddleware.Add(), uc.updateUserHandler)
|
||||
group.GET("/users/:id/groups", authMiddleware.Add(), uc.getUserGroupsHandler)
|
||||
group.GET("/users/:id/webauthn-credentials", authMiddleware.Add(), uc.listUserWebauthnCredentialsHandler)
|
||||
group.PUT("/users/me", authMiddleware.WithAdminNotRequired().Add(), uc.updateCurrentUserHandler)
|
||||
group.DELETE("/users/:id", authMiddleware.Add(), uc.deleteUserHandler)
|
||||
group.DELETE("/users/:id/webauthn-credentials/:credentialId", authMiddleware.Add(), uc.deleteUserWebauthnCredentialHandler)
|
||||
group.GET("/users", authMiddleware.Add(), httpserver.Handle(uc.listUsersHandler))
|
||||
group.GET("/users/me", authMiddleware.WithAdminNotRequired().Add(), httpserver.Handle(uc.getCurrentUserHandler))
|
||||
group.GET("/users/:id", authMiddleware.Add(), httpserver.Handle(uc.getUserHandler))
|
||||
group.POST("/users", authMiddleware.Add(), httpserver.Handle(uc.createUserHandler))
|
||||
group.PUT("/users/:id", authMiddleware.Add(), httpserver.Handle(uc.updateUserHandler))
|
||||
group.GET("/users/:id/groups", authMiddleware.Add(), httpserver.Handle(uc.getUserGroupsHandler))
|
||||
group.GET("/users/:id/webauthn-credentials", authMiddleware.Add(), httpserver.Handle(uc.listUserWebauthnCredentialsHandler))
|
||||
group.PUT("/users/me", authMiddleware.WithAdminNotRequired().Add(), httpserver.Handle(uc.updateCurrentUserHandler))
|
||||
group.DELETE("/users/:id", authMiddleware.Add(), httpserver.Handle(uc.deleteUserHandler))
|
||||
group.DELETE("/users/:id/webauthn-credentials/:credentialId", authMiddleware.Add(), httpserver.Handle(uc.deleteUserWebauthnCredentialHandler))
|
||||
|
||||
group.PUT("/users/:id/user-groups", authMiddleware.Add(), uc.updateUserGroups)
|
||||
group.PUT("/users/:id/user-groups", authMiddleware.Add(), httpserver.Handle(uc.updateUserGroups))
|
||||
|
||||
group.GET("/users/:id/profile-picture.png", uc.getUserProfilePictureHandler)
|
||||
group.GET("/users/:id/profile-picture.png", httpserver.Handle(uc.getUserProfilePictureHandler))
|
||||
|
||||
group.PUT("/users/:id/profile-picture", authMiddleware.Add(), uc.updateUserProfilePictureHandler)
|
||||
group.PUT("/users/me/profile-picture", authMiddleware.WithAdminNotRequired().Add(), uc.updateCurrentUserProfilePictureHandler)
|
||||
group.PUT("/users/:id/profile-picture", authMiddleware.Add(), httpserver.Handle(uc.updateUserProfilePictureHandler))
|
||||
group.PUT("/users/me/profile-picture", authMiddleware.WithAdminNotRequired().Add(), httpserver.Handle(uc.updateCurrentUserProfilePictureHandler))
|
||||
|
||||
group.DELETE("/users/:id/profile-picture", authMiddleware.Add(), uc.resetUserProfilePictureHandler)
|
||||
group.DELETE("/users/me/profile-picture", authMiddleware.WithAdminNotRequired().Add(), uc.resetCurrentUserProfilePictureHandler)
|
||||
group.DELETE("/users/:id/profile-picture", authMiddleware.Add(), httpserver.Handle(uc.resetUserProfilePictureHandler))
|
||||
group.DELETE("/users/me/profile-picture", authMiddleware.WithAdminNotRequired().Add(), httpserver.Handle(uc.resetCurrentUserProfilePictureHandler))
|
||||
}
|
||||
|
||||
type UserController struct {
|
||||
@@ -61,21 +62,20 @@ type UserController struct {
|
||||
// @Param id path string true "User ID"
|
||||
// @Success 200 {array} dto.UserGroupDto
|
||||
// @Router /api/users/{id}/groups [get]
|
||||
func (uc *UserController) getUserGroupsHandler(c *gin.Context) {
|
||||
func (uc *UserController) getUserGroupsHandler(c *gin.Context) error {
|
||||
userID := c.Param("id")
|
||||
groups, err := uc.userService.GetUserGroups(c.Request.Context(), userID)
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
var groupsDto []dto.UserGroupDto
|
||||
if err := dto.MapStructList(groups, &groupsDto); err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, groupsDto)
|
||||
return nil
|
||||
}
|
||||
|
||||
// listUserWebauthnCredentialsHandler godoc
|
||||
@@ -85,27 +85,25 @@ func (uc *UserController) getUserGroupsHandler(c *gin.Context) {
|
||||
// @Param id path string true "User ID"
|
||||
// @Success 200 {array} dto.WebauthnCredentialDto
|
||||
// @Router /api/users/{id}/webauthn-credentials [get]
|
||||
func (uc *UserController) listUserWebauthnCredentialsHandler(c *gin.Context) {
|
||||
func (uc *UserController) listUserWebauthnCredentialsHandler(c *gin.Context) error {
|
||||
userID := c.Param("id")
|
||||
|
||||
if _, err := uc.userService.GetUser(c.Request.Context(), userID); err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
credentials, err := uc.webAuthnService.ListCredentials(c.Request.Context(), userID)
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
var credentialDtos []dto.WebauthnCredentialDto
|
||||
if err := dto.MapStructList(credentials, &credentialDtos); err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, credentialDtos)
|
||||
return nil
|
||||
}
|
||||
|
||||
// listUsersHandler godoc
|
||||
@@ -119,26 +117,25 @@ func (uc *UserController) listUserWebauthnCredentialsHandler(c *gin.Context) {
|
||||
// @Param sort[direction] query string false "Sort direction (asc or desc)" default("asc")
|
||||
// @Success 200 {object} dto.Paginated[dto.UserDto]
|
||||
// @Router /api/users [get]
|
||||
func (uc *UserController) listUsersHandler(c *gin.Context) {
|
||||
func (uc *UserController) listUsersHandler(c *gin.Context) error {
|
||||
searchTerm := c.Query("search")
|
||||
listRequestOptions := utils.ParseListRequestOptions(c)
|
||||
|
||||
users, pagination, err := uc.userService.ListUsers(c.Request.Context(), searchTerm, listRequestOptions)
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
var usersDto []dto.UserDto
|
||||
if err := dto.MapStructList(users, &usersDto); err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, dto.Paginated[dto.UserDto]{
|
||||
Data: usersDto,
|
||||
Pagination: pagination,
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
// getUserHandler godoc
|
||||
@@ -148,20 +145,19 @@ func (uc *UserController) listUsersHandler(c *gin.Context) {
|
||||
// @Param id path string true "User ID"
|
||||
// @Success 200 {object} dto.UserDto
|
||||
// @Router /api/users/{id} [get]
|
||||
func (uc *UserController) getUserHandler(c *gin.Context) {
|
||||
func (uc *UserController) getUserHandler(c *gin.Context) error {
|
||||
user, err := uc.userService.GetUser(c.Request.Context(), c.Param("id"))
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
var userDto dto.UserDto
|
||||
if err := dto.MapStruct(user, &userDto); err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, userDto)
|
||||
return nil
|
||||
}
|
||||
|
||||
// getCurrentUserHandler godoc
|
||||
@@ -170,20 +166,19 @@ func (uc *UserController) getUserHandler(c *gin.Context) {
|
||||
// @Tags Users
|
||||
// @Success 200 {object} dto.UserDto
|
||||
// @Router /api/users/me [get]
|
||||
func (uc *UserController) getCurrentUserHandler(c *gin.Context) {
|
||||
func (uc *UserController) getCurrentUserHandler(c *gin.Context) error {
|
||||
user, err := uc.userService.GetUser(c.Request.Context(), c.GetString("userID"))
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
var userDto dto.UserDto
|
||||
if err := dto.MapStruct(user, &userDto); err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, userDto)
|
||||
return nil
|
||||
}
|
||||
|
||||
// deleteUserHandler godoc
|
||||
@@ -193,19 +188,18 @@ func (uc *UserController) getCurrentUserHandler(c *gin.Context) {
|
||||
// @Param id path string true "User ID"
|
||||
// @Success 204 "No Content"
|
||||
// @Router /api/users/{id} [delete]
|
||||
func (uc *UserController) deleteUserHandler(c *gin.Context) {
|
||||
func (uc *UserController) deleteUserHandler(c *gin.Context) error {
|
||||
dbConfig, err := uc.appConfigService.GetConfig(c.Request.Context())
|
||||
if err != nil {
|
||||
_ = c.Error(fmt.Errorf("error loading app configuration: %w", err))
|
||||
return
|
||||
return fmt.Errorf("error loading app configuration: %w", err)
|
||||
}
|
||||
|
||||
if err := uc.userService.DeleteUser(c.Request.Context(), dbConfig, c.Param("id"), false); err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
c.Status(http.StatusNoContent)
|
||||
return nil
|
||||
}
|
||||
|
||||
// deleteUserWebauthnCredentialHandler godoc
|
||||
@@ -216,7 +210,7 @@ func (uc *UserController) deleteUserHandler(c *gin.Context) {
|
||||
// @Param credentialId path string true "Credential ID"
|
||||
// @Success 204 "No Content"
|
||||
// @Router /api/users/{id}/webauthn-credentials/{credentialId} [delete]
|
||||
func (uc *UserController) deleteUserWebauthnCredentialHandler(c *gin.Context) {
|
||||
func (uc *UserController) deleteUserWebauthnCredentialHandler(c *gin.Context) error {
|
||||
err := uc.webAuthnService.DeleteCredential(
|
||||
c.Request.Context(),
|
||||
c.Param("id"),
|
||||
@@ -226,11 +220,11 @@ func (uc *UserController) deleteUserWebauthnCredentialHandler(c *gin.Context) {
|
||||
c.GetString("userID"),
|
||||
)
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
c.Status(http.StatusNoContent)
|
||||
return nil
|
||||
}
|
||||
|
||||
// createUserHandler godoc
|
||||
@@ -240,32 +234,29 @@ func (uc *UserController) deleteUserWebauthnCredentialHandler(c *gin.Context) {
|
||||
// @Param user body dto.UserCreateDto true "User information"
|
||||
// @Success 201 {object} dto.UserDto
|
||||
// @Router /api/users [post]
|
||||
func (uc *UserController) createUserHandler(c *gin.Context) {
|
||||
func (uc *UserController) createUserHandler(c *gin.Context) error {
|
||||
dbConfig, err := uc.appConfigService.GetConfig(c.Request.Context())
|
||||
if err != nil {
|
||||
_ = c.Error(fmt.Errorf("error loading app configuration: %w", err))
|
||||
return
|
||||
return fmt.Errorf("error loading app configuration: %w", err)
|
||||
}
|
||||
|
||||
var input dto.UserCreateDto
|
||||
if err := dto.ShouldBindWithNormalizedJSON(c, &input); err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
if err := httpserver.BindJSON(c, &input); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
user, err := uc.userService.CreateUser(c.Request.Context(), dbConfig, input)
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
var userDto dto.UserDto
|
||||
if err := dto.MapStruct(user, &userDto); err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
c.JSON(http.StatusCreated, userDto)
|
||||
return nil
|
||||
}
|
||||
|
||||
// updateUserHandler godoc
|
||||
@@ -276,8 +267,8 @@ func (uc *UserController) createUserHandler(c *gin.Context) {
|
||||
// @Param user body dto.UserCreateDto true "User information"
|
||||
// @Success 200 {object} dto.UserDto
|
||||
// @Router /api/users/{id} [put]
|
||||
func (uc *UserController) updateUserHandler(c *gin.Context) {
|
||||
uc.updateUser(c, false)
|
||||
func (uc *UserController) updateUserHandler(c *gin.Context) error {
|
||||
return uc.updateUser(c, false)
|
||||
}
|
||||
|
||||
// updateCurrentUserHandler godoc
|
||||
@@ -287,8 +278,8 @@ func (uc *UserController) updateUserHandler(c *gin.Context) {
|
||||
// @Param user body dto.UserCreateDto true "User information"
|
||||
// @Success 200 {object} dto.UserDto
|
||||
// @Router /api/users/me [put]
|
||||
func (uc *UserController) updateCurrentUserHandler(c *gin.Context) {
|
||||
uc.updateUser(c, true)
|
||||
func (uc *UserController) updateCurrentUserHandler(c *gin.Context) error {
|
||||
return uc.updateUser(c, true)
|
||||
}
|
||||
|
||||
// getUserProfilePictureHandler godoc
|
||||
@@ -299,13 +290,12 @@ func (uc *UserController) updateCurrentUserHandler(c *gin.Context) {
|
||||
// @Param id path string true "User ID"
|
||||
// @Success 200 {file} binary "PNG image"
|
||||
// @Router /api/users/{id}/profile-picture.png [get]
|
||||
func (uc *UserController) getUserProfilePictureHandler(c *gin.Context) {
|
||||
func (uc *UserController) getUserProfilePictureHandler(c *gin.Context) error {
|
||||
userID := c.Param("id")
|
||||
|
||||
picture, size, err := uc.userService.GetProfilePicture(c.Request.Context(), userID)
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
if picture != nil {
|
||||
defer picture.Close()
|
||||
@@ -314,6 +304,7 @@ func (uc *UserController) getUserProfilePictureHandler(c *gin.Context) {
|
||||
utils.SetCacheControlHeader(c, 15*time.Minute, 1*time.Hour)
|
||||
|
||||
c.DataFromReader(http.StatusOK, size, "image/png", picture, nil)
|
||||
return nil
|
||||
}
|
||||
|
||||
// updateUserProfilePictureHandler godoc
|
||||
@@ -326,26 +317,24 @@ func (uc *UserController) getUserProfilePictureHandler(c *gin.Context) {
|
||||
// @Param file formData file true "Profile picture image file (PNG, JPG, or JPEG)"
|
||||
// @Success 204 "No Content"
|
||||
// @Router /api/users/{id}/profile-picture [put]
|
||||
func (uc *UserController) updateUserProfilePictureHandler(c *gin.Context) {
|
||||
func (uc *UserController) updateUserProfilePictureHandler(c *gin.Context) error {
|
||||
userID := c.Param("id")
|
||||
fileHeader, err := c.FormFile("file")
|
||||
fileHeader, err := httpserver.FormFile(c, "file")
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
file, err := fileHeader.Open()
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
if err := uc.userService.UpdateProfilePicture(c.Request.Context(), userID, file); err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
c.Status(http.StatusNoContent)
|
||||
return nil
|
||||
}
|
||||
|
||||
// updateCurrentUserProfilePictureHandler godoc
|
||||
@@ -357,26 +346,24 @@ func (uc *UserController) updateUserProfilePictureHandler(c *gin.Context) {
|
||||
// @Param file formData file true "Profile picture image file (PNG, JPG, or JPEG)"
|
||||
// @Success 204 "No Content"
|
||||
// @Router /api/users/me/profile-picture [put]
|
||||
func (uc *UserController) updateCurrentUserProfilePictureHandler(c *gin.Context) {
|
||||
func (uc *UserController) updateCurrentUserProfilePictureHandler(c *gin.Context) error {
|
||||
userID := c.GetString("userID")
|
||||
fileHeader, err := c.FormFile("file")
|
||||
fileHeader, err := httpserver.FormFile(c, "file")
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
file, err := fileHeader.Open()
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
if err := uc.userService.UpdateProfilePicture(c.Request.Context(), userID, file); err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
c.Status(http.StatusNoContent)
|
||||
return nil
|
||||
}
|
||||
|
||||
// updateUserGroups godoc
|
||||
@@ -387,40 +374,36 @@ func (uc *UserController) updateCurrentUserProfilePictureHandler(c *gin.Context)
|
||||
// @Param groups body dto.UserUpdateUserGroupDto true "User group IDs"
|
||||
// @Success 200 {object} dto.UserDto
|
||||
// @Router /api/users/{id}/user-groups [put]
|
||||
func (uc *UserController) updateUserGroups(c *gin.Context) {
|
||||
func (uc *UserController) updateUserGroups(c *gin.Context) error {
|
||||
var input dto.UserUpdateUserGroupDto
|
||||
if err := c.ShouldBindJSON(&input); err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
if err := httpserver.BindJSON(c, &input); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
user, err := uc.userService.UpdateUserGroups(c.Request.Context(), c.Param("id"), input.UserGroupIds)
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
var userDto dto.UserDto
|
||||
if err := dto.MapStruct(user, &userDto); err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, userDto)
|
||||
return nil
|
||||
}
|
||||
|
||||
// updateUser is an internal helper method, not exposed as an API endpoint
|
||||
func (uc *UserController) updateUser(c *gin.Context, updateOwnUser bool) {
|
||||
func (uc *UserController) updateUser(c *gin.Context, updateOwnUser bool) error {
|
||||
dbConfig, err := uc.appConfigService.GetConfig(c.Request.Context())
|
||||
if err != nil {
|
||||
_ = c.Error(fmt.Errorf("error loading app configuration: %w", err))
|
||||
return
|
||||
return fmt.Errorf("error loading app configuration: %w", err)
|
||||
}
|
||||
|
||||
var input dto.UserCreateDto
|
||||
if err := dto.ShouldBindWithNormalizedJSON(c, &input); err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
if err := httpserver.BindJSON(c, &input); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var userID string
|
||||
@@ -432,17 +415,16 @@ func (uc *UserController) updateUser(c *gin.Context, updateOwnUser bool) {
|
||||
|
||||
user, err := uc.userService.UpdateUser(c.Request.Context(), dbConfig, userID, input, updateOwnUser, false)
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
var userDto dto.UserDto
|
||||
if err := dto.MapStruct(user, &userDto); err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, userDto)
|
||||
return nil
|
||||
}
|
||||
|
||||
// resetUserProfilePictureHandler godoc
|
||||
@@ -453,15 +435,15 @@ func (uc *UserController) updateUser(c *gin.Context, updateOwnUser bool) {
|
||||
// @Param id path string true "User ID"
|
||||
// @Success 204 "No Content"
|
||||
// @Router /api/users/{id}/profile-picture [delete]
|
||||
func (uc *UserController) resetUserProfilePictureHandler(c *gin.Context) {
|
||||
func (uc *UserController) resetUserProfilePictureHandler(c *gin.Context) error {
|
||||
userID := c.Param("id")
|
||||
|
||||
if err := uc.userService.ResetProfilePicture(c.Request.Context(), userID); err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
c.Status(http.StatusNoContent)
|
||||
return nil
|
||||
}
|
||||
|
||||
// resetCurrentUserProfilePictureHandler godoc
|
||||
@@ -471,13 +453,13 @@ func (uc *UserController) resetUserProfilePictureHandler(c *gin.Context) {
|
||||
// @Produce json
|
||||
// @Success 204 "No Content"
|
||||
// @Router /api/users/me/profile-picture [delete]
|
||||
func (uc *UserController) resetCurrentUserProfilePictureHandler(c *gin.Context) {
|
||||
func (uc *UserController) resetCurrentUserProfilePictureHandler(c *gin.Context) error {
|
||||
userID := c.GetString("userID")
|
||||
|
||||
if err := uc.userService.ResetProfilePicture(c.Request.Context(), userID); err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
c.Status(http.StatusNoContent)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/pocket-id/pocket-id/backend/internal/appconfig"
|
||||
"github.com/pocket-id/pocket-id/backend/internal/dto"
|
||||
"github.com/pocket-id/pocket-id/backend/internal/httpserver"
|
||||
"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/utils"
|
||||
@@ -25,13 +26,13 @@ func NewUserGroupController(group *gin.RouterGroup, authMiddleware *middleware.A
|
||||
userGroupsGroup := group.Group("/user-groups")
|
||||
userGroupsGroup.Use(authMiddleware.Add())
|
||||
{
|
||||
userGroupsGroup.GET("", ugc.list)
|
||||
userGroupsGroup.GET("/:id", ugc.get)
|
||||
userGroupsGroup.POST("", ugc.create)
|
||||
userGroupsGroup.PUT("/:id", ugc.update)
|
||||
userGroupsGroup.DELETE("/:id", ugc.delete)
|
||||
userGroupsGroup.PUT("/:id/users", ugc.updateUsers)
|
||||
userGroupsGroup.PUT("/:id/allowed-oidc-clients", ugc.updateAllowedOidcClients)
|
||||
userGroupsGroup.GET("", httpserver.Handle(ugc.list))
|
||||
userGroupsGroup.GET("/:id", httpserver.Handle(ugc.get))
|
||||
userGroupsGroup.POST("", httpserver.Handle(ugc.create))
|
||||
userGroupsGroup.PUT("/:id", httpserver.Handle(ugc.update))
|
||||
userGroupsGroup.DELETE("/:id", httpserver.Handle(ugc.delete))
|
||||
userGroupsGroup.PUT("/:id/users", httpserver.Handle(ugc.updateUsers))
|
||||
userGroupsGroup.PUT("/:id/allowed-oidc-clients", httpserver.Handle(ugc.updateAllowedOidcClients))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,14 +52,13 @@ type UserGroupController struct {
|
||||
// @Param sort[direction] query string false "Sort direction (asc or desc)" default("asc")
|
||||
// @Success 200 {object} dto.Paginated[dto.UserGroupMinimalDto]
|
||||
// @Router /api/user-groups [get]
|
||||
func (ugc *UserGroupController) list(c *gin.Context) {
|
||||
func (ugc *UserGroupController) list(c *gin.Context) error {
|
||||
searchTerm := c.Query("search")
|
||||
listRequestOptions := utils.ParseListRequestOptions(c)
|
||||
|
||||
groups, pagination, err := ugc.UserGroupService.List(c, searchTerm, listRequestOptions)
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
// Map the user groups to DTOs
|
||||
@@ -66,13 +66,11 @@ func (ugc *UserGroupController) list(c *gin.Context) {
|
||||
for i, group := range groups {
|
||||
var groupDto dto.UserGroupMinimalDto
|
||||
if err := dto.MapStruct(group, &groupDto); err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
groupDto.UserCount, err = ugc.UserGroupService.GetUserCountOfGroup(c.Request.Context(), group.ID)
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
groupsDto[i] = groupDto
|
||||
}
|
||||
@@ -81,6 +79,7 @@ func (ugc *UserGroupController) list(c *gin.Context) {
|
||||
Data: groupsDto,
|
||||
Pagination: pagination,
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
// get godoc
|
||||
@@ -92,20 +91,19 @@ func (ugc *UserGroupController) list(c *gin.Context) {
|
||||
// @Param id path string true "User Group ID"
|
||||
// @Success 200 {object} dto.UserGroupDto
|
||||
// @Router /api/user-groups/{id} [get]
|
||||
func (ugc *UserGroupController) get(c *gin.Context) {
|
||||
func (ugc *UserGroupController) get(c *gin.Context) error {
|
||||
group, err := ugc.UserGroupService.Get(c.Request.Context(), c.Param("id"))
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
var groupDto dto.UserGroupDto
|
||||
if err := dto.MapStruct(group, &groupDto); err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, groupDto)
|
||||
return nil
|
||||
}
|
||||
|
||||
// create godoc
|
||||
@@ -117,26 +115,24 @@ func (ugc *UserGroupController) get(c *gin.Context) {
|
||||
// @Param userGroup body dto.UserGroupCreateDto true "User group information"
|
||||
// @Success 201 {object} dto.UserGroupDto "Created user group"
|
||||
// @Router /api/user-groups [post]
|
||||
func (ugc *UserGroupController) create(c *gin.Context) {
|
||||
func (ugc *UserGroupController) create(c *gin.Context) error {
|
||||
var input dto.UserGroupCreateDto
|
||||
if err := dto.ShouldBindWithNormalizedJSON(c, &input); err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
if err := httpserver.BindJSON(c, &input); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
group, err := ugc.UserGroupService.Create(c.Request.Context(), input)
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
var groupDto dto.UserGroupDto
|
||||
if err := dto.MapStruct(group, &groupDto); err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
c.JSON(http.StatusCreated, groupDto)
|
||||
return nil
|
||||
}
|
||||
|
||||
// update godoc
|
||||
@@ -149,32 +145,29 @@ func (ugc *UserGroupController) create(c *gin.Context) {
|
||||
// @Param userGroup body dto.UserGroupCreateDto true "User group information"
|
||||
// @Success 200 {object} dto.UserGroupDto "Updated user group"
|
||||
// @Router /api/user-groups/{id} [put]
|
||||
func (ugc *UserGroupController) update(c *gin.Context) {
|
||||
func (ugc *UserGroupController) update(c *gin.Context) error {
|
||||
dbConfig, err := ugc.appConfigService.GetConfig(c.Request.Context())
|
||||
if err != nil {
|
||||
_ = c.Error(fmt.Errorf("error loading app configuration: %w", err))
|
||||
return
|
||||
return fmt.Errorf("error loading app configuration: %w", err)
|
||||
}
|
||||
|
||||
var input dto.UserGroupCreateDto
|
||||
if err := dto.ShouldBindWithNormalizedJSON(c, &input); err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
if err := httpserver.BindJSON(c, &input); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
group, err := ugc.UserGroupService.Update(c.Request.Context(), dbConfig, c.Param("id"), input)
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
var groupDto dto.UserGroupDto
|
||||
if err := dto.MapStruct(group, &groupDto); err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, groupDto)
|
||||
return nil
|
||||
}
|
||||
|
||||
// delete godoc
|
||||
@@ -186,19 +179,18 @@ func (ugc *UserGroupController) update(c *gin.Context) {
|
||||
// @Param id path string true "User Group ID"
|
||||
// @Success 204 "No Content"
|
||||
// @Router /api/user-groups/{id} [delete]
|
||||
func (ugc *UserGroupController) delete(c *gin.Context) {
|
||||
func (ugc *UserGroupController) delete(c *gin.Context) error {
|
||||
dbConfig, err := ugc.appConfigService.GetConfig(c.Request.Context())
|
||||
if err != nil {
|
||||
_ = c.Error(fmt.Errorf("error loading app configuration: %w", err))
|
||||
return
|
||||
return fmt.Errorf("error loading app configuration: %w", err)
|
||||
}
|
||||
|
||||
if err := ugc.UserGroupService.Delete(c.Request.Context(), dbConfig, c.Param("id")); err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
c.Status(http.StatusNoContent)
|
||||
return nil
|
||||
}
|
||||
|
||||
// updateUsers godoc
|
||||
@@ -211,26 +203,24 @@ func (ugc *UserGroupController) delete(c *gin.Context) {
|
||||
// @Param users body dto.UserGroupUpdateUsersDto true "List of user IDs to assign to this group"
|
||||
// @Success 200 {object} dto.UserGroupDto
|
||||
// @Router /api/user-groups/{id}/users [put]
|
||||
func (ugc *UserGroupController) updateUsers(c *gin.Context) {
|
||||
func (ugc *UserGroupController) updateUsers(c *gin.Context) error {
|
||||
var input dto.UserGroupUpdateUsersDto
|
||||
if err := c.ShouldBindJSON(&input); err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
if err := httpserver.BindJSON(c, &input); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
group, err := ugc.UserGroupService.UpdateUsers(c.Request.Context(), c.Param("id"), input.UserIDs)
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
var groupDto dto.UserGroupDto
|
||||
if err := dto.MapStruct(group, &groupDto); err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, groupDto)
|
||||
return nil
|
||||
}
|
||||
|
||||
// updateAllowedOidcClients godoc
|
||||
@@ -243,24 +233,22 @@ func (ugc *UserGroupController) updateUsers(c *gin.Context) {
|
||||
// @Param groups body dto.UserGroupUpdateAllowedOidcClientsDto true "OIDC client IDs to allow"
|
||||
// @Success 200 {object} dto.UserGroupDto "Updated user group"
|
||||
// @Router /api/user-groups/{id}/allowed-oidc-clients [put]
|
||||
func (ugc *UserGroupController) updateAllowedOidcClients(c *gin.Context) {
|
||||
func (ugc *UserGroupController) updateAllowedOidcClients(c *gin.Context) error {
|
||||
var input dto.UserGroupUpdateAllowedOidcClientsDto
|
||||
if err := c.ShouldBindJSON(&input); err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
if err := httpserver.BindJSON(c, &input); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
userGroup, err := ugc.UserGroupService.UpdateAllowedOidcClient(c.Request.Context(), c.Param("id"), input)
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
var userGroupDto dto.UserGroupDto
|
||||
if err := dto.MapStruct(userGroup, &userGroupDto); err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, userGroupDto)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/pocket-id/pocket-id/backend/internal/common"
|
||||
"github.com/pocket-id/pocket-id/backend/internal/httpserver"
|
||||
"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/utils"
|
||||
@@ -14,8 +15,8 @@ import (
|
||||
// NewVersionController registers version-related routes.
|
||||
func NewVersionController(group *gin.RouterGroup, authMiddleware *middleware.AuthMiddleware, versionService *service.VersionService) {
|
||||
vc := &VersionController{versionService: versionService}
|
||||
group.GET("/version/latest", vc.getLatestVersionHandler)
|
||||
group.GET("/version/current", authMiddleware.WithAdminNotRequired().Add(), vc.getCurrentVersionHandler)
|
||||
group.GET("/version/latest", httpserver.Handle(vc.getLatestVersionHandler))
|
||||
group.GET("/version/current", authMiddleware.WithAdminNotRequired().Add(), httpserver.Handle(vc.getCurrentVersionHandler))
|
||||
}
|
||||
|
||||
type VersionController struct {
|
||||
@@ -28,11 +29,10 @@ type VersionController struct {
|
||||
// @Produce json
|
||||
// @Success 200 {object} map[string]string "Latest version information"
|
||||
// @Router /api/version/latest [get]
|
||||
func (vc *VersionController) getLatestVersionHandler(c *gin.Context) {
|
||||
func (vc *VersionController) getLatestVersionHandler(c *gin.Context) error {
|
||||
tag, err := vc.versionService.GetLatestVersion(c.Request.Context())
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
utils.SetCacheControlHeader(c, 5*time.Minute, 15*time.Minute)
|
||||
@@ -40,6 +40,7 @@ func (vc *VersionController) getLatestVersionHandler(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"latestVersion": tag,
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
// getCurrentVersionHandler godoc
|
||||
@@ -48,9 +49,9 @@ func (vc *VersionController) getLatestVersionHandler(c *gin.Context) {
|
||||
// @Produce json
|
||||
// @Success 200 {object} map[string]string "Current version information"
|
||||
// @Router /api/version/current [get]
|
||||
func (vc *VersionController) getCurrentVersionHandler(c *gin.Context) {
|
||||
|
||||
func (vc *VersionController) getCurrentVersionHandler(c *gin.Context) error {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"currentVersion": common.Version,
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"github.com/pocket-id/pocket-id/backend/internal/common"
|
||||
"github.com/pocket-id/pocket-id/backend/internal/httpserver"
|
||||
"github.com/pocket-id/pocket-id/backend/internal/service"
|
||||
)
|
||||
|
||||
@@ -21,8 +22,8 @@ func NewWellKnownController(group *gin.RouterGroup, jwtService *service.JwtServi
|
||||
getCIMDURLAllowlist: getCIMDURLAllowlist,
|
||||
}
|
||||
|
||||
group.GET("/.well-known/jwks.json", wkc.jwksHandler)
|
||||
group.GET("/.well-known/openid-configuration", wkc.openIDConfigurationHandler)
|
||||
group.GET("/.well-known/jwks.json", httpserver.Handle(wkc.jwksHandler))
|
||||
group.GET("/.well-known/openid-configuration", httpserver.Handle(wkc.openIDConfigurationHandler))
|
||||
}
|
||||
|
||||
type WellKnownController struct {
|
||||
@@ -37,14 +38,14 @@ type WellKnownController struct {
|
||||
// @Produce json
|
||||
// @Success 200 {object} object "{ \"keys\": []interface{} }"
|
||||
// @Router /.well-known/jwks.json [get]
|
||||
func (wkc *WellKnownController) jwksHandler(c *gin.Context) {
|
||||
func (wkc *WellKnownController) jwksHandler(c *gin.Context) error {
|
||||
jwks, err := wkc.jwtService.GetPublicJWKSAsJSON()
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
c.Data(http.StatusOK, "application/json; charset=utf-8", jwks)
|
||||
return nil
|
||||
}
|
||||
|
||||
// openIDConfigurationHandler godoc
|
||||
@@ -53,13 +54,13 @@ func (wkc *WellKnownController) jwksHandler(c *gin.Context) {
|
||||
// @Tags Well Known
|
||||
// @Success 200 {object} object "OpenID Connect configuration"
|
||||
// @Router /.well-known/openid-configuration [get]
|
||||
func (wkc *WellKnownController) openIDConfigurationHandler(c *gin.Context) {
|
||||
func (wkc *WellKnownController) openIDConfigurationHandler(c *gin.Context) error {
|
||||
oidcConfig, err := wkc.computeOIDCConfiguration()
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
c.Data(http.StatusOK, "application/json; charset=utf-8", oidcConfig)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (wkc *WellKnownController) computeOIDCConfiguration() ([]byte, error) {
|
||||
|
||||
Reference in New Issue
Block a user