2025-01-29 15:23:56 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								package  resources  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"bytes" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"context" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"encoding/json" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"io" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"math" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"net/http" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"strconv" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"strings" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/zitadel/logging" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									scim_config  "github.com/zitadel/zitadel/internal/api/scim/config" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/zitadel/zitadel/internal/api/scim/metadata" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/zitadel/zitadel/internal/api/scim/schemas" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/zitadel/zitadel/internal/api/scim/serrors" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/zitadel/zitadel/internal/zerrors" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  BulkHandler  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cfg                           * scim_config . BulkConfig 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									handlersByPluralResourceName  map [ schemas . ScimResourceTypePlural ] RawResourceHandlerAdapter 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  BulkRequest  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Schemas       [ ] schemas . ScimSchemaType  ` json:"schemas" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									FailOnErrors  * int                      ` json:"failOnErrors" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Operations    [ ] * BulkRequestOperation   ` json:"Operations" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  BulkRequestOperation  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Method  string           ` json:"method" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									BulkID  string           ` json:"bulkId" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Path    string           ` json:"path" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Data    json . RawMessage  ` json:"data" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  BulkResponse  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Schemas     [ ] schemas . ScimSchemaType  ` json:"schemas" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Operations  [ ] * BulkResponseOperation  ` json:"Operations" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  BulkResponseOperation  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Method    string              ` json:"method" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									BulkID    string              ` json:"bulkId,omitempty" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Location  string              ` json:"location,omitempty" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Error     * serrors . ScimError  ` json:"response,omitempty" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Status    string              ` json:"status" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( r  * BulkRequest )  GetSchemas ( )  [ ] schemas . ScimSchemaType  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  r . Schemas 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  NewBulkHandler (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cfg  scim_config . BulkConfig , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									handlers  ... RawResourceHandlerAdapter , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  * BulkHandler  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									handlersByPluralResourceName  :=  make ( map [ schemas . ScimResourceTypePlural ] RawResourceHandlerAdapter ,  len ( handlers ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  handler  :=  range  handlers  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-29 19:11:12 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										handlersByPluralResourceName [ handler . Schema ( ) . PluralName ]  =  handler 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-29 15:23:56 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  & BulkHandler { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										& cfg , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										handlersByPluralResourceName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( h  * BulkHandler )  BulkFromHttp ( r  * http . Request )  ( * BulkResponse ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									req ,  err  :=  h . readBulkRequest ( r ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  h . processRequest ( r . Context ( ) ,  req ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( h  * BulkHandler )  readBulkRequest ( r  * http . Request )  ( * BulkRequest ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									request  :=  new ( BulkRequest ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  :=  readSchema ( r . Body ,  request ,  schemas . IdBulkRequest ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  len ( request . Operations )  >  h . cfg . MaxOperationsCount  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  serrors . ThrowPayloadTooLarge ( zerrors . ThrowInvalidArgumentf ( nil ,  "SCIM-BLK19" ,  "Too many bulk operations in one request, max %d allowed." ,  h . cfg . MaxOperationsCount ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  request ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( h  * BulkHandler )  processRequest ( ctx  context . Context ,  req  * BulkRequest )  ( * BulkResponse ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									errorBudget  :=  math . MaxInt32 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  req . FailOnErrors  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										errorBudget  =  * req . FailOnErrors 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									resp  :=  & BulkResponse { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Schemas :     [ ] schemas . ScimSchemaType { schemas . IdBulkResponse } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Operations :  make ( [ ] * BulkResponseOperation ,  0 ,  len ( req . Operations ) ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  operation  :=  range  req . Operations  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										opResp  :=  h . processOperation ( ctx ,  operation ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										resp . Operations  =  append ( resp . Operations ,  opResp ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  opResp . Error  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										errorBudget -- 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  errorBudget  <=  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  resp ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  resp ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( h  * BulkHandler )  processOperation ( ctx  context . Context ,  op  * BulkRequestOperation )  ( opResp  * BulkResponseOperation )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  statusCode  int 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  resourceNamePlural  schemas . ScimResourceTypePlural 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  resourceID  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  err  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									opResp  =  & BulkResponseOperation { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Method :  op . Method , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										BulkID :  op . BulkID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  func ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  r  :=  recover ( ) ;  r  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											logging . WithFields ( "panic" ,  r ) . Error ( "Bulk operation panic" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											err  =  zerrors . ThrowInternal ( nil ,  "SCIM-BLK12" ,  "Internal error while processing bulk operation" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  resourceNamePlural  !=  ""  &&  resourceID  !=  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-29 19:11:12 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											opResp . Location  =  schemas . BuildLocationForResource ( ctx ,  resourceNamePlural ,  resourceID ) 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-29 15:23:56 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										opResp . Status  =  strconv . Itoa ( statusCode ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											opResp . Error  =  serrors . MapToScimError ( ctx ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											opResp . Status  =  opResp . Error . Status 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									resourceNamePlural ,  resourceID ,  err  =  h . parsePath ( op . Path ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  opResp 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									resourceID ,  err  =  metadata . ResolveScimBulkIDIfNeeded ( ctx ,  resourceID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  opResp 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									resourceHandler ,  ok  :=  h . handlersByPluralResourceName [ resourceNamePlural ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  =  zerrors . ThrowInvalidArgumentf ( nil ,  "SCIM-BLK13" ,  "Unknown resource %s" ,  resourceNamePlural ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  opResp 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  op . Method  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  http . MethodPatch : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										statusCode  =  http . StatusNoContent 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  =  h . processPatchOperation ( ctx ,  resourceHandler ,  resourceID ,  op . Data ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  http . MethodPut : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										statusCode  =  http . StatusOK 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  =  h . processPutOperation ( ctx ,  resourceHandler ,  resourceID ,  op ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  http . MethodPost : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										statusCode  =  http . StatusCreated 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										resourceID ,  err  =  h . processPostOperation ( ctx ,  resourceHandler ,  resourceID ,  op ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  http . MethodDelete : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										statusCode  =  http . StatusNoContent 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  =  h . processDeleteOperation ( ctx ,  resourceHandler ,  resourceID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  =  zerrors . ThrowInvalidArgumentf ( nil ,  "SCIM-BLK14" ,  "Unsupported operation %s" ,  op . Method ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  opResp 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( h  * BulkHandler )  processPutOperation ( ctx  context . Context ,  resourceHandler  RawResourceHandlerAdapter ,  resourceID  string ,  op  * BulkRequestOperation )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									data  :=  io . NopCloser ( bytes . NewReader ( op . Data ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									_ ,  err  :=  resourceHandler . Replace ( ctx ,  resourceID ,  data ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( h  * BulkHandler )  processPostOperation ( ctx  context . Context ,  resourceHandler  RawResourceHandlerAdapter ,  resourceID  string ,  op  * BulkRequestOperation )  ( string ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  resourceID  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  "" ,  zerrors . ThrowInvalidArgumentf ( nil ,  "SCIM-BLK56" ,  "Cannot post with a resourceID" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									data  :=  io . NopCloser ( bytes . NewReader ( op . Data ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									createdResource ,  err  :=  resourceHandler . Create ( ctx ,  data ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  "" ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									id  :=  createdResource . GetResource ( ) . ID 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  op . BulkID  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										metadata . SetScimBulkIDMapping ( ctx ,  op . BulkID ,  id ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  id ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( h  * BulkHandler )  processPatchOperation ( ctx  context . Context ,  resourceHandler  RawResourceHandlerAdapter ,  resourceID  string ,  data  json . RawMessage )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  resourceID  ==  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  zerrors . ThrowInvalidArgumentf ( nil ,  "SCIM-BLK16" ,  "To patch a resource, a resourceID is required" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  resourceHandler . Update ( ctx ,  resourceID ,  io . NopCloser ( bytes . NewReader ( data ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( h  * BulkHandler )  processDeleteOperation ( ctx  context . Context ,  resourceHandler  RawResourceHandlerAdapter ,  resourceID  string )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  resourceID  ==  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  zerrors . ThrowInvalidArgumentf ( nil ,  "SCIM-BLK17" ,  "To delete a resource, a resourceID is required" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  resourceHandler . Delete ( ctx ,  resourceID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( h  * BulkHandler )  parsePath ( path  string )  ( schemas . ScimResourceTypePlural ,  string ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! strings . HasPrefix ( path ,  "/" )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  "" ,  "" ,  zerrors . ThrowInvalidArgumentf ( nil ,  "SCIM-BLK19" ,  "Invalid path: has to start with a /" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// part 0 is always an empty string due to the leading / 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pathParts  :=  strings . Split ( path ,  "/" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  len ( pathParts )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  2 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  schemas . ScimResourceTypePlural ( pathParts [ 1 ] ) ,  "" ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  3 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  schemas . ScimResourceTypePlural ( pathParts [ 1 ] ) ,  pathParts [ 2 ] ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  "" ,  "" ,  zerrors . ThrowInvalidArgumentf ( nil ,  "SCIM-BLK20" ,  "Invalid resource path" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}