2025-01-09 12:46:36 +01:00
package resources
import (
"encoding/json"
"net/http"
"slices"
2025-01-09 15:12:13 +01:00
"github.com/gorilla/mux"
2025-01-27 13:36:07 +01:00
"github.com/zitadel/zitadel/internal/api/scim/resources/patch"
2025-01-09 12:46:36 +01:00
"github.com/zitadel/zitadel/internal/api/scim/serrors"
"github.com/zitadel/zitadel/internal/zerrors"
)
type ResourceHandlerAdapter [ T ResourceHolder ] struct {
handler ResourceHandler [ T ]
}
func NewResourceHandlerAdapter [ T ResourceHolder ] ( handler ResourceHandler [ T ] ) * ResourceHandlerAdapter [ T ] {
return & ResourceHandlerAdapter [ T ] {
handler ,
}
}
func ( adapter * ResourceHandlerAdapter [ T ] ) Create ( r * http . Request ) ( T , error ) {
entity , err := adapter . readEntityFromBody ( r )
if err != nil {
return entity , err
}
return adapter . handler . Create ( r . Context ( ) , entity )
}
2025-01-14 15:44:41 +01:00
func ( adapter * ResourceHandlerAdapter [ T ] ) Replace ( r * http . Request ) ( T , error ) {
entity , err := adapter . readEntityFromBody ( r )
if err != nil {
return entity , err
}
id := mux . Vars ( r ) [ "id" ]
return adapter . handler . Replace ( r . Context ( ) , id , entity )
}
2025-01-27 13:36:07 +01:00
func ( adapter * ResourceHandlerAdapter [ T ] ) Update ( r * http . Request ) error {
request := new ( patch . OperationRequest )
err := json . NewDecoder ( r . Body ) . Decode ( request )
if err != nil {
if zerrors . IsZitadelError ( err ) {
return err
}
return serrors . ThrowInvalidSyntax ( zerrors . ThrowInvalidArgumentf ( nil , "SCIM-ucrjson2" , "Could not deserialize json: %v" , err . Error ( ) ) )
}
err = request . Validate ( )
if err != nil {
return err
}
if len ( request . Operations ) == 0 {
return nil
}
id := mux . Vars ( r ) [ "id" ]
return adapter . handler . Update ( r . Context ( ) , id , request . Operations )
}
2025-01-09 15:12:13 +01:00
func ( adapter * ResourceHandlerAdapter [ T ] ) Delete ( r * http . Request ) error {
id := mux . Vars ( r ) [ "id" ]
return adapter . handler . Delete ( r . Context ( ) , id )
}
2025-01-21 13:31:54 +01:00
func ( adapter * ResourceHandlerAdapter [ T ] ) List ( r * http . Request ) ( * ListResponse [ T ] , error ) {
request , err := readListRequest ( r )
if err != nil {
return nil , err
}
return adapter . handler . List ( r . Context ( ) , request )
}
2025-01-10 12:15:06 +01:00
func ( adapter * ResourceHandlerAdapter [ T ] ) Get ( r * http . Request ) ( T , error ) {
id := mux . Vars ( r ) [ "id" ]
return adapter . handler . Get ( r . Context ( ) , id )
}
2025-01-09 12:46:36 +01:00
func ( adapter * ResourceHandlerAdapter [ T ] ) readEntityFromBody ( r * http . Request ) ( T , error ) {
entity := adapter . handler . NewResource ( )
err := json . NewDecoder ( r . Body ) . Decode ( entity )
if err != nil {
2025-01-21 13:31:54 +01:00
if serrors . IsScimOrZitadelError ( err ) {
2025-01-09 12:46:36 +01:00
return entity , err
}
return entity , serrors . ThrowInvalidSyntax ( zerrors . ThrowInvalidArgumentf ( nil , "SCIM-ucrjson" , "Could not deserialize json: %v" , err . Error ( ) ) )
}
resource := entity . GetResource ( )
if resource == nil {
return entity , serrors . ThrowInvalidSyntax ( zerrors . ThrowInvalidArgument ( nil , "SCIM-xxrjson" , "Could not get resource, is the schema correct?" ) )
}
if ! slices . Contains ( resource . Schemas , adapter . handler . SchemaType ( ) ) {
return entity , serrors . ThrowInvalidSyntax ( zerrors . ThrowInvalidArgumentf ( nil , "SCIM-xxrschema" , "Expected schema %v is not provided" , adapter . handler . SchemaType ( ) ) )
}
return entity , nil
}