scimprotocol

package module
v0.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 19, 2026 License: MIT Imports: 25 Imported by: 0

README

Go Reference

SingleStore-Lab/scim — SCIM 2.0 library for Go

A Go (Golang) library for building a SCIM 2.0 server that receives identity provisioning requests from identity providers (IdPs) such as Microsoft Entra ID (Azure AD) and Okta.

SCIM is the System for Cross-domain Identity Management. This package implements the SCIM protocol and core schema so you can expose User and Group endpoints, parse filters and PATCH paths, and marshal SCIM JSON. Attribute behavior follows RFC 7643 SCIM characteristics declared as scim struct tags.

  • RFC 7642 — SCIM definitions, overview, and requirements
  • RFC 7643 — SCIM core schema (User, Group, schemas, resource types)
  • RFC 7644 — SCIM protocol (HTTP API, filter, PATCH, pagination, attribute selection)

Import: github.com/singlestore-labs/scim
Package: scimprotocol
API docs: pkg.go.dev/github.com/singlestore-labs/scim

The library does not include persistence. To use it, you must supply a persistence layer meeting the API.

A working in-memory SCIM HTTP server is in scimtest.

Features

  • SCIM characteristics (RFC 7643 §7): required, caseExact, mutability, returned, uniqueness, canonicalValues...
  • SCIM 2.0 Users and Groups (and other resource types you define)
  • HTTP router for SCIM endpoints (/Users, /Groups, /Schemas, /ResourceTypes, /ServiceProviderConfig)
  • Filter parser and evaluation (userName eq "bjensen", nested multi-value filters)
  • PATCH add / remove / replace, including Azure-style filter-add on multi-value attributes
  • SCIM marshal / unmarshal driven by SCIM characteristics (scim struct tags)
  • Handler helpers that sit in front of your own database or storage layer

SCIM characteristics

RFC 7643 §7 attribute characteristics are declared on every field with a scim tag. They control marshal, unmarshal, filter, PATCH, and /Schemas output. See scimtag/characteristics.go.

Example: `scim:"userName,returned=always,required"`

Characteristic Tag Used for
name first tag token JSON name, filter/PATCH path, schemas
required required / !required unmarshal validation
caseExact caseExact / !caseExact filter comparison
mutability mutability= PATCH / update (readWrite, readOnly, immutable, writeOnly)
returned returned= marshal / attributes= selection (default, keepEmpty, always, never, request)
uniqueness uniqueness= scope of the unique value: none, server, or global
canonicalValues canonicalValues= allowed values in schemas (e.g. email type: work)
referenceTypes referenceTypes= resource types a $ref may point to — e.g. a User's groups.$ref with referenceTypes=User Group
ignoreUnmarshal ignoreUnmarshal skip unmarshal (id, meta)

returned=keepEmpty is an extension (emitted as default in schemas) so some attributes can stay visible while others omit empty values — useful for Azure AD / Entra ID and other IdPs.

Usage

  1. Define SCIM Resources

    func init() {
    	scimtag.BuildAllSCIMCharacsCache(SCIMUser{}, SCIMGroup{})
    }
    
    type SCIMUser struct {
    	scimprotocol.SCIMResourceMarker
    	UserID   *uuid.User
    	CoreUser `scim:"urn:ietf:params:scim:schemas:core:2.0:User"` // core schema required to be the first field with a scim tag
    	Meta     SCIMMeta                                            `scim:"meta,ignoreUnmarshal,returned=always"`
    }
    
    var _ scimprotocol.Resource = SCIMUser{}
    
    type CoreUser struct {
    	Active            bool          `scim:"active,returned=keepEmpty"`
    	DisplayName       string        `scim:"displayName,caseExact"`
    	Emails            []Email       `scim:"emails"`
    	Entitlements      []Entitlement `scim:"entitlements"`
    	ExternalID        string        `scim:"externalId"`
    	Groups            []Group       `scim:"groups,mutability=readOnly"`
    	ID                string        `scim:"id,returned=always,ignoreUnmarshal"`
    	Name              Name          `scim:"name"`
    	PreferredLanguage string        `scim:"preferredLanguage"`
    	Roles             []Role        `scim:"roles"`
    	Timezone          string        `scim:"timezone"`
    	Title             string        `scim:"title"`
    	UserName          string        `scim:"userName,required"`
    	UserType          string        `scim:"userType"`
    }
    
    type Email struct {
    	Value   string `scim:"value"`
    	Type    string `scim:"type,canonicalValues=work"` // azure only allow `work`
    	Primary bool   `scim:"primary,returned=keepEmpty"`
    }
    
    type SCIMMeta struct {
    	Created      time.Time `json:"created" scim:"created,returned=always"` // SCIM characteristics need specify at all level
    	LastModified time.Time `json:"lastModified" scim:"lastModified,returned=always"`
    }
    
    • SCIM resources like User and Group must implement the Resource interface (embed SCIMResourceMarker).
    • When defining SCIM resources, the type need to be unique. Here is Why
    • Multi-Value attributes, like email, checks duplicate on whole object by default. You can customize comparation by implementing interface MultiValueElement.
    • Define scim tags for SCIM characteristics
      • First position of the tag is the attribute name. Characteristics are separated by ,.
      • bool or !bool in the tag is true or false (required, caseExact, ignoreUnmarshal).
      • Empty canonical values in schemas: canonicalValues= .
      • Characteristics must be set on nested structs as well (see SCIMMeta above).
  2. Create SCIM endpoints

    scimrouter is available to use, check example in scimtest folder.

    You can also create your own router and server with helper function below.

    • Use this library to create a HTTP server:
      • Use functions in handlerhelper.go (or do something similar) with your persistency layer to create a HTTP server
    • Use scimmarshal.go to marshal/unmarshal when the data goes through endpoints

Marshal&Unmarshal

This library has its own SCIM marshal with scim tag scim. Marshal and unmarshal follow SCIM characteristics.

returned controls marshal:

  • returned=default omit empty
  • returned=keepEmpty include empty values
  • returned=request marshal only when selected
  • returned=never never marshal, even if selected
  • returned=always always marshal, even if not selected

required and ignoreUnmarshal control unmarshal.

This library supports customization marshal, however, if you use SCIMMarshaler/SCIMUnmarshaler, then filter and patch will not works on that resource.

	type SCIMMarshaler interface {
		MarshalSCIM(selectedAttr []string, excludeSelected bool) ([]byte, error)
	}

	type SCIMUnmarshaler interface {
		UnmarshalSCIM([]byte) error
	}

The PrimaryDataType interface helps support customized primary data type not in the rfc, like ID to support UUID type. Example: TestMarshalObject

You could also use string for ID and convert it to your type at outside of this Library.

type PrimaryDataType interface {
	SCIMCompareValue(op string, stringValue string, azureAdd bool) (bool, error)
}

Code

  1. parser - parse input query contains filter or patch with path.
  2. filter - after parse we need evaluate a resource, like a user or a group, to check if it's passes the filter or not.
  3. patch - patch needs to walk down the path along with filter to the target value and modifies it.
  4. marshal - marshal and unmarshal SCIM object with characteristics and support features like checking schema, select attributes.
    • customized SCIM marshal by implementing SCIMMarshaler.
  5. scim tag - include SCIM characteristics and tag cache.
  6. handlerhelper - helper functions helps easily interact with database/storage layer for those handler functions when building SCIM http server.

Azure tweaks

Azure uses filter in a patch to add new element for multi-value attributes. Like if non of the element can pass filter then it will add one with the value in the patch. Use azureFilterAdd to trigger support adding elements to multi-value attributes with filters.

Note

This repo does not contains name and description in schemas because they are optional in RFC.

Documentation

Overview

Package scimprotocol implements SCIM 2.0 (RFC 7643 and RFC 7644) for receiving provisioning requests from identity providers.

The import path is github.com/singlestore-labs/scim.

Resources

Define User, Group, and other resources by embedding SCIMResourceMarker and tagging fields with scim struct tags. See github.com/singlestore-labs/scim/scimtag for supported characteristics. Call github.com/singlestore-labs/scim/scimtag.BuildAllSCIMCharacsCache once at startup for each resource type.

HTTP endpoints

Implement Server and pass it to SCIMRouter, or build your own handlers with helpers such as GetResourceHelper and GetListResourceHelper. Marshal and unmarshal with Marshal and Unmarshal; they honor scim tags for attribute selection, required fields, and empty-value handling.

A complete in-memory example lives in the scimtest package.

Index

Constants

This section is empty.

Variables

View Source
var Lex = lexer.MustSimple([]lexer.SimpleRule{

	{Name: "String", Pattern: stringPattern},
	{Name: "Number", Pattern: numberPattern},
	{Name: "URI", Pattern: uriPattern},
	{Name: "Ident", Pattern: `[a-zA-Z][-a-zA-Z0-9_]*`},
	{Name: "(", Pattern: `\(`},
	{Name: ")", Pattern: `\)`},
	{Name: "[", Pattern: `\[`},
	{Name: "]", Pattern: `\]`},
	{Name: "Whitespace", Pattern: `[ \t]+`},
	{Name: "Dot", Pattern: `\.`},
	{Name: "Colon", Pattern: `\:`},
})

Lex tokenizes shapes only, never keywords.

Rules are distinguishable by their first character, so ordering is only significant for URI, which must precede Ident.

View Source
var URIPattenRegexp = regexp.MustCompile(uriPattern)

Functions

func CompareValueAddIfAzure

func CompareValueAddIfAzure(target reflect.Value, targetCharacs *scimtag.Characteristics, op CompareOp, value string, azureAdd bool) (bool, error)

CompareValueAddIfAzure compare the target reflect value with input op and value. if azureAdd is true, it will set the target value when op is 'eq'.

func CreateResourceHelper

func CreateResourceHelper[T Resource](
	r *http.Request,
	scimID string,
	createResourceToDB func(_ context.Context, scimID string, _ T) (T, error),
) (nvelope.Response, error)

func EvalHelper

func EvalHelper(e Expression, p *Node, objV reflect.Value, scimCharacs *scimtag.Characteristics, azureFilterAdd bool) (bool, error)

EvalHelper is a function that evaluates filter expressions against refelect.Value objects scimCharacs should be nil when object is not SCIM attribute

azureFilterAdd is hacky way to be compatible with azure's 'add' patch. Following patch should add new email that fit the filter and value. since it's hacky way so currently only support following two, no more complex op.

{
	"op": "add",
	"path": "emails[type eq \"work\"].value",
	"value": "zoey@mcglynn.name"
},
{
	"op": "add",
	"path": "emails[type eq \"work\"].primary",
	"value": true
},

the azureFilterAdd should only be turned on in patch processing when op is 'add'.

func GetFilteredResources

func GetFilteredResources[T Resource](filter *OrExpression, inputs []T) ([]T, error)

func GetListResourceHelper

func GetListResourceHelper[T Resource](
	r *http.Request,
	trace util.Trace,
	defaultPageSize int,
	scimID string,
	getAllResourceData func(ctx context.Context, scimID string) ([]T, error),
) (nvelope.Response, error)

func GetResourceHelper

func GetResourceHelper[T Resource](
	r *http.Request,
	scimID string,
	resourceID string,
	getResourceData func(ctx context.Context, scimID string, resourceID string) (T, error),
) (nvelope.Response, error)

func GetSCIMDataType

func GetSCIMDataType(t reflect.Type, scimAttrName string) (string, error)

func GetSchemasHelper

func GetSchemasHelper(resourceTypes []ResourceType) (nvelope.Response, error)

func Marshal

func Marshal(obj any) ([]byte, error)

func MarshalWithSelectedAttr

func MarshalWithSelectedAttr(obj any, selectedAttr []string, excludeSelected bool) (_ []byte, err error)

func Patch

func Patch(objV reflect.Value, path *Node, op string, value []byte) error

path = nil: patch on the end of path path = &Node: patch on root

func PatchResourceHelper

func PatchResourceHelper[T Resource](
	r *http.Request,
	scimID string,
	resourceID string,
	getResourceFromDB func(ctx context.Context, scimID string, resourceID string) (T, error),
	updateResourceToDB func(ctx context.Context, scimID string, resourceID string, _ T) (T, error),
) (nvelope.Response, error)

func Unmarshal

func Unmarshal(data []byte, obj any) (err error)

Unmarshal not required to be resource, since we need it in patch to unmarshal attribute

func UpdateResourceHelper

func UpdateResourceHelper[T Resource](
	r *http.Request,
	scimID string,
	resourceID string,
	updateResourceToDB func(_ context.Context, scimID string, resourceID string, _ T) (T, error),
) (nvelope.Response, error)

Types

type AndTerm

type AndTerm struct {
	Left  Expr   `parser:"@@"` // Expr will be recursive parse either Expression or Not(Group)
	Right []Expr `parser:"(Whitespace 'and' Whitespace @@)*"`
}

func (AndTerm) Eval

func (ot AndTerm) Eval(v reflect.Value, azureAdd bool) (bool, error)

func (AndTerm) RedactedString

func (e AndTerm) RedactedString() string

func (AndTerm) String

func (e AndTerm) String() string

func (AndTerm) ToSqlizer

func (e AndTerm) ToSqlizer(sg SQLGenerator, not bool) (sq.Sqlizer, error)

type AttributeSchema

type AttributeSchema struct {
	Name            string             `json:"name"`
	Type            string             `json:"type"`
	MultiValued     bool               `json:"multiValued"`
	Required        bool               `json:"required"`
	CaseExact       *bool              `json:"caseExact,omitempty"`
	Mutability      scimtag.Mutability `json:"mutability"`
	Returned        scimtag.Returned   `json:"returned"`
	Uniqueness      *string            `json:"uniqueness,omitempty"`
	CanonicalValues *[]string          `json:"canonicalValues,omitempty"`
	ReferenceTypes  []string           `json:"referenceTypes,omitempty"`
	SubAttributes   []AttributeSchema  `json:"subAttributes,omitempty"`
}

type AuthType

type AuthType string
const AuthTypeOauthBearerToken AuthType = "oauthbearertoken"

type AuthenticationScheme

type AuthenticationScheme struct {
	Name             string   `json:"name"`
	Description      string   `json:"description"`
	SpecURI          string   `json:"specUri"`
	DocumentationURI string   `json:"documentationUri"`
	Type             AuthType `json:"type"`
	Primary          bool     `json:"primary"`
}

type Common

type Common interface {
	Eval(v reflect.Value, azureAdd bool) (bool, error)
	String() string
	ToSqlizer(sg SQLGenerator, not bool) (sq.Sqlizer, error)
}

type CompValue added in v0.0.2

type CompValue string

CompValue holds the raw JSON literal of a comparison value, quotes included for strings, so that it stays consumable by json.Unmarshal.

compValue = false / null / true / number / string ; rules from JSON (RFC 7159)

func (*CompValue) Capture added in v0.0.2

func (c *CompValue) Capture(values []string) error

Capture stores the raw token. JSON keywords must already be lowercase (RFC 7159). Ident matching is case-insensitive, so we throw error here when the value is not lowercase. Like, `TRUE` would pass Ident matching but error here on capture.

type CompareOp added in v0.0.2

type CompareOp string
const (
	OpPR CompareOp = "pr"
	OpEQ CompareOp = "eq"
	OpNE CompareOp = "ne"
	OpCO CompareOp = "co"
	OpSW CompareOp = "sw"
	OpEW CompareOp = "ew"
	OpGT CompareOp = "gt"
	OpLT CompareOp = "lt"
	OpGE CompareOp = "ge"
	OpLE CompareOp = "le"
)

RFC 7644 §3.4.2.2 attribute operators. The parser tag on Expression is the allow-list; these constants are for Go comparisons after Capture.

func (*CompareOp) Capture added in v0.0.2

func (c *CompareOp) Capture(values []string) error

Capture normalizes the operator, which RFC 7644 §3.4.2.2 defines as case-insensitive, so callers can compare against the constants above.

type Config

type Config struct {
	DefaultPageSize       int
	PatchSupported        bool
	BulkSupported         bool
	BulkMaxOperations     int
	BulkMaxPayloadSize    int
	FilterSupported       bool
	FilterMaxResult       int
	ChangePassword        bool
	SortSupported         bool
	EtagSupported         bool
	AuthenticationSchemas []AuthenticationScheme
}

func (Config) MarshalSCIM

func (r Config) MarshalSCIM(reqURL string) ([]byte, error)

type EndpointSCIMID

type EndpointSCIMID struct {
	SCIMID string `nvelope:"path,name=scimID"`
}

type EndpointSCIMIDAndResourceID

type EndpointSCIMIDAndResourceID struct {
	SCIMID     string `nvelope:"path,name=scimID"`
	ResourceID string `nvelope:"path,name=resourceID"`
}

type Expr

type Expr interface {
	RedactedString() string

	Common
	// contains filtered or unexported methods
}

Expr should be implement by Expression and NotExpression (which include OrExpression)

type Expression

type Expression struct {
	Path Path `parser:"@@"`
	// Operator is optional, like `emails[type eq "work"]`
	CompareOp CompareOp `parser:"(Whitespace (@'pr' | (@('eq'|'ne'|'co'|'sw'|'ew'|'gt'|'lt'|'ge'|'le')"`
	Value     CompValue `parser:"  Whitespace @(String|Number|'true'|'false'|'null'))))?"`
}

Expression is an attribute expression.

attrExp = (attrPath SP "pr") / (attrPath SP compareOp SP compValue)

func (Expression) Eval

func (e Expression) Eval(v reflect.Value, azureAdd bool) (bool, error)

func (Expression) RedactedString

func (e Expression) RedactedString() string

func (Expression) String

func (e Expression) String() string

func (Expression) ToSqlizer

func (e Expression) ToSqlizer(sg SQLGenerator, not bool) (sq.Sqlizer, error)

type ListResponse

type ListResponse[T any] struct {
	Resources    []T
	StartIndex   int
	ItemsPerPage int // return actual items number per page
	TotalResults int
}

func (ListResponse[T]) MarshalSCIM

func (l ListResponse[T]) MarshalSCIM(selectedAttr []string, excludeSelected bool) ([]byte, error)

type MultiValueElement

type MultiValueElement interface {
	// contains filtered or unexported methods
}

type Node

type Node struct {
	Value any
	Next  *Node
}

type NotExpression

type NotExpression struct {
	Not   bool         `parser:"(@'not' Whitespace?)?"`
	Group OrExpression `parser:"'(' Whitespace? @@ Whitespace? ')'"`
}

NotExpression is a grouped filter, optionally negated. 'not' has the highest precedence so it sits at the deepest level.

FILTER = ... / *1"not" "(" FILTER ")"

The ABNF puts no SP after "not" while the RFC examples and identity providers send "not (", so both are accepted.

func (NotExpression) Eval

func (sg NotExpression) Eval(v reflect.Value, azureAdd bool) (bool, error)

func (NotExpression) RedactedString

func (ne NotExpression) RedactedString() string

func (NotExpression) String

func (ne NotExpression) String() string

func (NotExpression) ToSqlizer

func (ne NotExpression) ToSqlizer(sg SQLGenerator, not bool) (sq.Sqlizer, error)

type OrExpression

type OrExpression struct {
	Left  *AndTerm   `parser:"@@"`
	Right []*AndTerm `parser:"(Whitespace 'or' Whitespace @@)*"`
}

func ParseFilter

func ParseFilter(filterStr string) (*OrExpression, error)

func (OrExpression) Eval

func (le OrExpression) Eval(v reflect.Value, azureAdd bool) (bool, error)

Eval evaluates the OrExpression against the given reflect.Value v. The azureAdd parameter indicates whether to apply Azure-specific filtering logic. Detail explained in filter.go EvalHelper.

func (OrExpression) RedactedString

func (oe OrExpression) RedactedString() string

func (OrExpression) String

func (oe OrExpression) String() string

func (OrExpression) ToSqlizer

func (oe OrExpression) ToSqlizer(sg SQLGenerator, not bool) (sq.Sqlizer, error)

type PatchOperation

type PatchOperation struct {
	Op    string          `json:"op"`
	Path  string          `json:"path"`
	Value json.RawMessage `json:"value"`
}

func UnmarshalPatchRequest

func UnmarshalPatchRequest(data []byte) ([]PatchOperation, error)

type Path

type Path struct {
	URI         string        `parser:"(@URI"`
	Colon       string        `parser:"  ':')?"`
	AttrName    string        `parser:"@Ident"`
	Filter      *OrExpression `parser:"('[' Whitespace? @@  Whitespace?']')?"`
	SubAttrName string        `parser:"('.'@Ident)?"`
}

func ParsePath

func ParsePath(pathStr string) (*Path, error)

func (*Path) GetNodes

func (p *Path) GetNodes(coreSchemaID string) *Node

GetNodes returns a linked list from Path for recursive when filter, patch and marshal. It returns dummyhead node (empty node) followed by path nodes. If path is nil (no path), then return nil. If the node is the last one (end path), then node.Next is nil.

func (Path) String

func (p Path) String() string

type PrimaryDataType

type PrimaryDataType interface {
	SCIMCompareValue(op CompareOp, stringValue string, azureAdd bool) (bool, error)
}

type Resource

type Resource interface {
	// contains filtered or unexported methods
}

type ResourceType

type ResourceType struct {
	ID                 string           `json:"id,omitempty"`
	Name               string           `json:"name"`
	Endpoint           string           `json:"endpoint"` // "/Users" or "/Groups"
	Description        string           `json:"description,omitempty"`
	ResourceObjectType reflect.Type     `json:"-"`
	Meta               ResourceTypeMeta `json:"meta"`
}

func (ResourceType) MarshalSCIM

func (r ResourceType) MarshalSCIM([]string, bool) ([]byte, error)

type ResourceTypeMeta

type ResourceTypeMeta struct {
	Location     string `json:"location"`
	ResourceType string `json:"resourceType"`
}

type SCIMConnectionErr

type SCIMConnectionErr error

type SCIMMarshaler

type SCIMMarshaler interface {
	MarshalSCIM(selectedAttr []string, excludeSelected bool) ([]byte, error)
}

SCIMMarshaler and SCIMUnmarshaler allow customized marshal and unmarshal for SCIM Note: if you choose to have SCIMMarshaler or SCIMUnmarshaler, means you take full control of marshal. And the patch and filter may not work as expected.

type SCIMResourceMarker

type SCIMResourceMarker struct{}

type SCIMUnmarshaler

type SCIMUnmarshaler interface {
	UnmarshalSCIM([]byte) error
}

type SQLGenerator

type SQLGenerator interface {
	// sq.And, sq.Or, sq.Eq .... returns sq.Sqlizer
	Generate(Common, bool) (sq.Sqlizer, error)
}

SQLGenerator is a interface used to convert expression to sql with SICM tag

type Schema

type Schema struct {
	ID         string            `json:"id"`
	Attributes []AttributeSchema `json:"attributes"`
}

Schema's name and description is option in rfc and not fit in scim tag, so not include for now.

func GetResourceSchema

func GetResourceSchema(resourceT reflect.Type) (schemas []Schema, err error)

resource is User or Groups or... , that User contains Core User attributes group and Extensions attributes group

func (Schema) MarshalSCIM

func (s Schema) MarshalSCIM([]string, bool) ([]byte, error)

type SchemaExtention

type SchemaExtention struct {
	Schema   string `json:"schema"`
	Required bool   `json:"required"`
}

func GetSchemaURIFromResource

func GetSchemaURIFromResource(resourceT reflect.Type, resourceVforFilterEmpty *reflect.Value) (coreSchemaURI string, extensions []SchemaExtention, err error)

GetSchemaURIFromResource is a helper function to get schema URI and extension URIs for ResourceType from self-defined SCIM resource struct, like User, Group resourceV is only needed when you need filter out empty URI struct, like extension URI should not include in when it's empty during marshal if input type is not Resource, then return ErrNotFound error if input type is Resource but doesn't have URI, return error

type Server

type Server interface {
	// Authorization middleware for SCIM requests
	Authorization(inner func() error, r *http.Request) error

	// GetResourceTypes returns the list of supported resource types
	GetResourceTypes() []ResourceType

	// Resource handlers for individual resource operations
	GetResourceHandler(r *http.Request, resourceType ResourceType, params EndpointSCIMIDAndResourceID) (nvelope.Response, error)
	GetResourceListHandler(r *http.Request, resourceType ResourceType, params EndpointSCIMID) (nvelope.Response, error)
	PostResourceHandler(r *http.Request, resourceType ResourceType, params EndpointSCIMID) (nvelope.Response, error)
	UpdateResourceHandler(r *http.Request, resourceType ResourceType, params EndpointSCIMIDAndResourceID) (nvelope.Response, error)
	PatchResourceHandler(r *http.Request, resourceType ResourceType, params EndpointSCIMIDAndResourceID) (nvelope.Response, error)
	DeleteResourceHandler(r *http.Request, resourceType ResourceType, params EndpointSCIMIDAndResourceID) (nvelope.Response, error)

	// Bulk operations handler
	BulkHandler() (nvelope.Response, error)

	// SCIM metadata handlers
	GetResourceTypesHandler() (nvelope.Response, error)
	SchemasHandler() (nvelope.Response, error)
	GetServiceProviderConfigHandler(r *http.Request, w http.ResponseWriter) (nvelope.Response, error)
}

Directories

Path Synopsis
Package scimerror defines SCIM protocol errors as specified in RFC 7644 section 3.12.
Package scimerror defines SCIM protocol errors as specified in RFC 7644 section 3.12.
Package scimtag parses scim struct tags into RFC 7643 attribute characteristics and caches them for marshal, unmarshal, filter, patch, and schema generation.
Package scimtag parses scim struct tags into RFC 7643 attribute characteristics and caches them for marshal, unmarshal, filter, patch, and schema generation.
Package scimtest is an in-memory example SCIM server used by tests and as a usage example for github.com/singlestore-labs/scim.
Package scimtest is an in-memory example SCIM server used by tests and as a usage example for github.com/singlestore-labs/scim.
e2e
Package util provides small helpers used by the SCIM protocol implementation and its tests.
Package util provides small helpers used by the SCIM protocol implementation and its tests.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL