Files
pocket-id/backend/internal/controller/scim_controller.go
2026-07-10 16:31:45 -05:00

97 lines
3.5 KiB
Go

package controller
import (
"context"
"net/http"
"github.com/danielgtaylor/huma/v2"
"github.com/pocket-id/pocket-id/backend/internal/dto"
"github.com/pocket-id/pocket-id/backend/internal/middleware"
"github.com/pocket-id/pocket-id/backend/internal/service"
httpapi "github.com/pocket-id/pocket-id/backend/internal/utils/huma"
)
type scimIDInput struct {
ID string `path:"id"`
}
type scimCreateInput struct {
Body dto.ScimServiceProviderCreateDTO
}
type scimUpdateInput struct {
ID string `path:"id"`
Body dto.ScimServiceProviderCreateDTO
}
func NewScimController(api huma.API, authMiddleware *middleware.AuthMiddleware, scimService *service.ScimService) {
controller := &ScimController{scimService: scimService}
auth := authMiddleware.Huma(api)
createOperation := scimOperation("create-scim-service-provider", http.MethodPost, "/api/scim/service-provider", "Create SCIM service provider")
createOperation.DefaultStatus = http.StatusCreated
auth(&createOperation)
httpapi.Register(api, createOperation, controller.createServiceProviderHandler)
syncOperation := scimOperation("sync-scim-service-provider", http.MethodPost, "/api/scim/service-provider/{id}/sync", "Sync SCIM service provider")
syncOperation.DefaultStatus = http.StatusOK
auth(&syncOperation)
httpapi.Register(api, syncOperation, controller.syncServiceProviderHandler)
updateOperation := scimOperation("update-scim-service-provider", http.MethodPut, "/api/scim/service-provider/{id}", "Update SCIM service provider")
auth(&updateOperation)
httpapi.Register(api, updateOperation, controller.updateServiceProviderHandler)
deleteOperation := scimOperation("delete-scim-service-provider", http.MethodDelete, "/api/scim/service-provider/{id}", "Delete SCIM service provider")
deleteOperation.DefaultStatus = http.StatusNoContent
auth(&deleteOperation)
httpapi.Register(api, deleteOperation, controller.deleteServiceProviderHandler)
}
func scimOperation(id, method, path, summary string) huma.Operation {
return huma.Operation{OperationID: id, Method: method, Path: path, Summary: summary, Tags: []string{"SCIM"}}
}
type ScimController struct {
scimService *service.ScimService
}
func (c *ScimController) syncServiceProviderHandler(ctx context.Context, input *scimIDInput) (*httpapi.EmptyOutput, error) {
if err := c.scimService.SyncServiceProvider(ctx, input.ID); err != nil {
return nil, err
}
return &httpapi.EmptyOutput{}, nil
}
func (c *ScimController) createServiceProviderHandler(ctx context.Context, input *scimCreateInput) (*httpapi.BodyOutput[dto.ScimServiceProviderDTO], error) {
provider, err := c.scimService.CreateServiceProvider(ctx, &input.Body)
if err != nil {
return nil, err
}
return mapSCIMProvider(provider)
}
func (c *ScimController) updateServiceProviderHandler(ctx context.Context, input *scimUpdateInput) (*httpapi.BodyOutput[dto.ScimServiceProviderDTO], error) {
provider, err := c.scimService.UpdateServiceProvider(ctx, input.ID, &input.Body)
if err != nil {
return nil, err
}
return mapSCIMProvider(provider)
}
func (c *ScimController) deleteServiceProviderHandler(ctx context.Context, input *scimIDInput) (*httpapi.EmptyOutput, error) {
if err := c.scimService.DeleteServiceProvider(ctx, input.ID); err != nil {
return nil, err
}
return &httpapi.EmptyOutput{}, nil
}
func mapSCIMProvider(provider any) (*httpapi.BodyOutput[dto.ScimServiceProviderDTO], error) {
var output dto.ScimServiceProviderDTO
if err := dto.MapStruct(provider, &output); err != nil {
return nil, err
}
return &httpapi.BodyOutput[dto.ScimServiceProviderDTO]{Body: output}, nil
}