Documentation
¶
Overview ¶
Package scim provides SCIM 2.0 (RFC 7643/7644) support for identity provisioning.
Index ¶
- Constants
- Variables
- func AuthScopesFromContext(ctx context.Context) []string
- func AuthSubjectFromContext(ctx context.Context) string
- func GenerateETag(version string) string
- func HasAuthScope(ctx context.Context, scope string) bool
- func LoggerFromContext(ctx context.Context) *slog.Logger
- func ParseETag(etag string) string
- func ParseScopes(scopeString string) []string
- func RequestIDFromContext(ctx context.Context) string
- func RolesFromContext(ctx context.Context) []string
- func ScopesString(scopes []string) string
- func ValidateScopes(scopes []string) []string
- func WithAuthScopes(ctx context.Context, scopes []string) context.Context
- func WithAuthSubject(ctx context.Context, subject string) context.Context
- func WithRequestID(ctx context.Context, requestID string) context.Context
- func WithRoles(ctx context.Context, roles []string) context.Context
- func WriteError(w http.ResponseWriter, err *Error)
- func WriteResponse(w http.ResponseWriter, status int, etag string, body []byte)
- type API
- func (a *API) Huma() huma.API
- func (a *API) Logger() *slog.Logger
- func (a *API) Middleware(authFn func(r *http.Request) (subject string, scopes []string, err error)) func(http.Handler) http.Handler
- func (a *API) Provider() *Provider
- func (a *API) Router() chi.Router
- func (a *API) ServeHTTP(w http.ResponseWriter, r *http.Request)
- type Address
- type AttributeFilter
- type AuthenticationScheme
- type AuthorizationHook
- type BcryptHasher
- type BulkInput
- type BulkOperation
- type BulkOutput
- type BulkRequest
- type BulkResponse
- type BulkResponseOperation
- type CompositeAuthorizationHook
- func (h *CompositeAuthorizationHook) CanCreate(ctx context.Context, resourceType string) error
- func (h *CompositeAuthorizationHook) CanDelete(ctx context.Context, resourceType, resourceID string) error
- func (h *CompositeAuthorizationHook) CanRead(ctx context.Context, resourceType, resourceID string) error
- func (h *CompositeAuthorizationHook) CanUpdate(ctx context.Context, resourceType, resourceID string) error
- type Config
- type CreateGroupInput
- type CreateGroupOutput
- type CreateUserInput
- type CreateUserOutput
- type DefaultAuthorizationHook
- func (DefaultAuthorizationHook) CanCreate(ctx context.Context, resourceType string) error
- func (DefaultAuthorizationHook) CanDelete(ctx context.Context, resourceType, resourceID string) error
- func (DefaultAuthorizationHook) CanRead(ctx context.Context, resourceType, resourceID string) error
- func (DefaultAuthorizationHook) CanUpdate(ctx context.Context, resourceType, resourceID string) error
- type DeleteResourceInput
- type EnterpriseUser
- type Error
- func ErrBadRequest(detail string) *Error
- func ErrConflict(detail string) *Error
- func ErrForbidden(detail string) *Error
- func ErrInternal(detail string) *Error
- func ErrInvalidFilter(detail string) *Error
- func ErrInvalidPath(detail string) *Error
- func ErrInvalidSyntax(detail string) *Error
- func ErrInvalidValue(detail string) *Error
- func ErrMutability(detail string) *Error
- func ErrNoTarget(detail string) *Error
- func ErrNotFound(detail string) *Error
- func ErrNotImplemented(detail string) *Error
- func ErrPreconditionFailed(detail string) *Error
- func ErrTooMany(detail string) *Error
- func ErrUnauthorized(detail string) *Error
- func NewError(status int, scimType, detail string) *Error
- func ToSCIMError(err error) *Error
- type GetGroupOutput
- type GetResourceInput
- type GetResourceTypeOutput
- type GetSchemaOutput
- type GetUserOutput
- type Group
- type GroupRef
- type ListGroupsOutput
- type ListOptions
- type ListResourceTypesOutput
- type ListResourcesInput
- type ListResponse
- type ListSchemasOutput
- type ListUsersOutput
- type ManagerRef
- type MeOutput
- type MePatchInput
- type MemberRef
- type Meta
- type MultiValue
- type Name
- type NoOpHasher
- type Option
- type PasswordHasher
- type PatchOperation
- type PatchRequest
- type PatchResourceInput
- type Provider
- type ProviderOption
- type RequestMetadata
- type Resource
- type ResourceTypeNameInput
- type RoleBasedAuthorizationHook
- func (h *RoleBasedAuthorizationHook) CanCreate(ctx context.Context, resourceType string) error
- func (h *RoleBasedAuthorizationHook) CanDelete(ctx context.Context, resourceType, resourceID string) error
- func (h *RoleBasedAuthorizationHook) CanRead(ctx context.Context, resourceType, resourceID string) error
- func (h *RoleBasedAuthorizationHook) CanUpdate(ctx context.Context, resourceType, resourceID string) error
- type SchemaIDInput
- type ScopedAuthorizationHook
- func (h *ScopedAuthorizationHook) CanCreate(ctx context.Context, resourceType string) error
- func (h *ScopedAuthorizationHook) CanDelete(ctx context.Context, resourceType, resourceID string) error
- func (h *ScopedAuthorizationHook) CanRead(ctx context.Context, resourceType, resourceID string) error
- func (h *ScopedAuthorizationHook) CanUpdate(ctx context.Context, resourceType, resourceID string) error
- type SearchInput
- type SearchOutput
- type SearchRequest
- type Service
- type ServiceProviderConfigOutput
- type Store
- type UpdateGroupInput
- type UpdateGroupOutput
- type UpdateUserInput
- type UpdateUserOutput
- type User
Constants ¶
const ( // User scopes ScopeUsersRead = "scim:users:read" ScopeUsersWrite = "scim:users:write" // Group scopes ScopeGroupsRead = "scim:groups:read" ScopeGroupsWrite = "scim:groups:write" // Full access scope ScopeFull = "scim:full" )
SCIM authorization scopes follow the pattern: scim:{resource}:{action}
const ( // ErrorTypeInvalidFilter indicates the filter syntax is invalid. ErrorTypeInvalidFilter = "invalidFilter" // ErrorTypeTooMany indicates too many results would be returned. ErrorTypeTooMany = "tooMany" // ErrorTypeUniqueness indicates a uniqueness constraint was violated. ErrorTypeUniqueness = "uniqueness" // ErrorTypeMutability indicates an attempt to modify an immutable attribute. ErrorTypeMutability = "mutability" // ErrorTypeInvalidSyntax indicates the request body is invalid. ErrorTypeInvalidSyntax = "invalidSyntax" // ErrorTypeInvalidPath indicates an invalid attribute path. ErrorTypeInvalidPath = "invalidPath" // ErrorTypeNoTarget indicates no target resource was found for a PATCH operation. ErrorTypeNoTarget = "noTarget" // ErrorTypeInvalidValue indicates an invalid attribute value. ErrorTypeInvalidValue = "invalidValue" // ErrorTypeInvalidVers indicates an invalid version for optimistic locking. ErrorTypeInvalidVers = "invalidVers" // ErrorTypeSensitive indicates a sensitive attribute cannot be returned. ErrorTypeSensitive = "sensitive" )
SCIM error types as defined in RFC 7644 Section 3.12.
const ( ResourceTypeUser = "User" ResourceTypeGroup = "Group" )
Resource types for SCIM endpoints.
Variables ¶
var ( SchemaUser = schema.URIUser SchemaGroup = schema.URIGroup SchemaEnterpriseUser = schema.URIEnterpriseUser SchemaListResponse = schema.URIListResponse SchemaPatchOp = schema.URIPatchOp SchemaBulkRequest = schema.URIBulkRequest SchemaBulkResponse = schema.URIBulkResponse SchemaError = schema.URIError )
Schema URIs for SCIM resource types (re-exported from schema package for convenience).
Functions ¶
func AuthScopesFromContext ¶
AuthScopesFromContext extracts the authenticated scopes from context.
func AuthSubjectFromContext ¶
AuthSubjectFromContext extracts the authenticated subject from context.
func GenerateETag ¶
GenerateETag generates an ETag value from a version string or timestamp.
func HasAuthScope ¶
HasAuthScope checks if the context has a specific scope.
func LoggerFromContext ¶
LoggerFromContext returns the logger from context, or slog.Default() if not set.
func ParseScopes ¶
ParseScopes parses a space-separated scope string into a slice.
func RequestIDFromContext ¶
RequestIDFromContext extracts the request ID from context.
func RolesFromContext ¶
RolesFromContext extracts roles from the context.
func ScopesString ¶
ScopesString converts a scope slice to a space-separated string.
func ValidateScopes ¶
ValidateScopes validates that the provided scopes are known SCIM scopes.
func WithAuthScopes ¶
WithAuthScopes adds the authenticated scopes to the context.
func WithAuthSubject ¶
WithAuthSubject adds the authenticated subject (user/client ID) to the context.
func WithRequestID ¶
WithRequestID adds a request ID to the context.
func WriteError ¶
func WriteError(w http.ResponseWriter, err *Error)
WriteError writes a SCIM error response to the HTTP response writer.
func WriteResponse ¶
func WriteResponse(w http.ResponseWriter, status int, etag string, body []byte)
WriteResponse writes a SCIM response with proper headers.
Types ¶
type API ¶
type API struct {
// contains filtered or unexported fields
}
API provides HTTP handlers for SCIM 2.0 endpoints using Huma/Chi.
func (*API) Middleware ¶
func (a *API) Middleware(authFn func(r *http.Request) (subject string, scopes []string, err error)) func(http.Handler) http.Handler
Middleware returns HTTP middleware for SCIM authentication. The authFn should validate the request and return the subject and scopes.
type Address ¶
type Address struct {
Formatted string `json:"formatted,omitempty"`
StreetAddress string `json:"streetAddress,omitempty"`
Locality string `json:"locality,omitempty"`
Region string `json:"region,omitempty"`
PostalCode string `json:"postalCode,omitempty"`
Country string `json:"country,omitempty"`
Type string `json:"type,omitempty"`
Primary bool `json:"primary,omitempty"`
}
Address represents a physical address.
type AttributeFilter ¶
type AttributeFilter struct {
// Attributes to include (if empty, include all)
Attributes []string
// Attributes to exclude
ExcludedAttributes []string
}
AttributeFilter filters SCIM resources to include/exclude specific attributes.
func NewAttributeFilter ¶
func NewAttributeFilter(attributes, excludedAttributes []string) *AttributeFilter
NewAttributeFilter creates a new attribute filter.
func (*AttributeFilter) FilterGroup ¶
func (f *AttributeFilter) FilterGroup(group *Group) *Group
FilterGroup applies attribute filtering to a Group resource.
func (*AttributeFilter) FilterListResponse ¶
func (f *AttributeFilter) FilterListResponse(response *ListResponse) *ListResponse
FilterListResponse applies attribute filtering to all resources in a list response.
func (*AttributeFilter) FilterResource ¶
func (f *AttributeFilter) FilterResource(resource any) any
FilterResource applies attribute filtering to any SCIM resource.
func (*AttributeFilter) FilterUser ¶
func (f *AttributeFilter) FilterUser(user *User) *User
FilterUser applies attribute filtering to a User resource.
func (*AttributeFilter) IsEmpty ¶
func (f *AttributeFilter) IsEmpty() bool
IsEmpty returns true if no filtering is configured.
type AuthenticationScheme ¶
type AuthenticationScheme struct {
Type string `json:"type"`
Name string `json:"name"`
Description string `json:"description"`
SpecURI string `json:"specUri,omitempty"`
DocumentationURI string `json:"documentationUri,omitempty"`
Primary bool `json:"primary,omitempty"`
}
AuthenticationScheme describes a supported authentication method.
type AuthorizationHook ¶
type AuthorizationHook interface {
// CanRead checks if the authenticated user can read the resource.
CanRead(ctx context.Context, resourceType, resourceID string) error
// CanCreate checks if the authenticated user can create resources of this type.
CanCreate(ctx context.Context, resourceType string) error
// CanUpdate checks if the authenticated user can update the resource.
CanUpdate(ctx context.Context, resourceType, resourceID string) error
// CanDelete checks if the authenticated user can delete the resource.
CanDelete(ctx context.Context, resourceType, resourceID string) error
}
AuthorizationHook provides authorization checks for SCIM operations.
type BcryptHasher ¶
type BcryptHasher struct {
// Cost is the bcrypt cost parameter. Default is bcrypt.DefaultCost (10).
Cost int
}
BcryptHasher implements PasswordHasher using bcrypt.
func NewBcryptHasher ¶
func NewBcryptHasher(cost int) *BcryptHasher
NewBcryptHasher creates a new bcrypt password hasher.
func (*BcryptHasher) Hash ¶
func (h *BcryptHasher) Hash(password string) (string, error)
Hash hashes a password using bcrypt.
func (*BcryptHasher) Verify ¶
func (h *BcryptHasher) Verify(password, hash string) error
Verify compares a password with a bcrypt hash.
type BulkInput ¶
type BulkInput struct {
Body *BulkRequest `doc:"Bulk request containing multiple operations"`
}
BulkInput contains the request body for bulk operations.
type BulkOperation ¶
type BulkOperation struct {
Method string `json:"method"`
BulkID string `json:"bulkId,omitempty"`
Version string `json:"version,omitempty"`
Path string `json:"path"`
Data any `json:"data,omitempty"`
}
BulkOperation represents a single operation within a bulk request.
type BulkOutput ¶
type BulkOutput struct {
Body *BulkResponse
}
BulkOutput is the response for bulk operations.
type BulkRequest ¶
type BulkRequest struct {
Schemas []string `json:"schemas"`
FailOnErrors int `json:"failOnErrors,omitempty"`
Operations []BulkOperation `json:"Operations"`
}
BulkRequest represents a SCIM bulk request as defined in RFC 7644 Section 3.7.
type BulkResponse ¶
type BulkResponse struct {
Schemas []string `json:"schemas"`
Operations []BulkResponseOperation `json:"Operations"`
}
BulkResponse represents a SCIM bulk response.
type BulkResponseOperation ¶
type BulkResponseOperation struct {
Method string `json:"method"`
BulkID string `json:"bulkId,omitempty"`
Version string `json:"version,omitempty"`
Location string `json:"location,omitempty"`
Status string `json:"status"`
Response any `json:"response,omitempty"`
}
BulkResponseOperation represents a single operation result within a bulk response.
type CompositeAuthorizationHook ¶
type CompositeAuthorizationHook struct {
// contains filtered or unexported fields
}
CompositeAuthorizationHook combines multiple authorization hooks. All hooks must pass for the operation to be allowed.
func NewCompositeAuthorizationHook ¶
func NewCompositeAuthorizationHook(hooks ...AuthorizationHook) *CompositeAuthorizationHook
NewCompositeAuthorizationHook creates a hook that combines multiple hooks.
func (*CompositeAuthorizationHook) CanCreate ¶
func (h *CompositeAuthorizationHook) CanCreate(ctx context.Context, resourceType string) error
CanCreate checks if all hooks allow creating the resource type.
func (*CompositeAuthorizationHook) CanDelete ¶
func (h *CompositeAuthorizationHook) CanDelete(ctx context.Context, resourceType, resourceID string) error
CanDelete checks if all hooks allow deleting the resource.
type Config ¶
type Config struct {
// BaseURL is the base URL for SCIM resources (e.g., "https://example.com/scim/v2").
BaseURL string
// MaxResults is the maximum number of resources returned in a list response.
MaxResults int
// DefaultPageSize is the default number of resources per page.
DefaultPageSize int
// SupportFiltering indicates whether filtering is supported.
SupportFiltering bool
// SupportSorting indicates whether sorting is supported.
SupportSorting bool
// SupportPatch indicates whether PATCH operations are supported.
SupportPatch bool
// SupportBulk indicates whether bulk operations are supported.
SupportBulk bool
// BulkMaxOperations is the maximum number of operations in a bulk request.
BulkMaxOperations int
// BulkMaxPayloadSize is the maximum size of a bulk request in bytes.
BulkMaxPayloadSize int
// SupportChangePassword indicates whether password changes via SCIM are supported.
SupportChangePassword bool
// SupportETag indicates whether ETag-based optimistic locking is supported.
SupportETag bool
// AuthenticationSchemes defines the supported authentication methods.
AuthenticationSchemes []AuthenticationScheme
// DocumentationURI is an optional URI to SCIM documentation.
DocumentationURI string
}
Config holds the SCIM server configuration.
func DefaultConfig ¶
func DefaultConfig() *Config
DefaultConfig returns a Config with sensible defaults.
func (*Config) GroupLocation ¶
GroupLocation returns the full URL for a group resource.
func (*Config) ResourceLocation ¶
ResourceLocation returns the full URL for a resource.
func (*Config) UserLocation ¶
UserLocation returns the full URL for a user resource.
type CreateGroupInput ¶
type CreateGroupInput struct {
Body *Group `doc:"Group resource to create"`
}
CreateGroupInput contains the request body for creating a group.
type CreateGroupOutput ¶
type CreateGroupOutput struct {
Body *Group
Location string `header:"Location" doc:"URI of the created resource"`
ETag string `header:"ETag" doc:"Entity tag for caching and conditional requests"`
}
CreateGroupOutput is the response for creating a group.
type CreateUserInput ¶
type CreateUserInput struct {
Body *User `doc:"User resource to create"`
}
CreateUserInput contains the request body for creating a user.
type CreateUserOutput ¶
type CreateUserOutput struct {
Body *User
Location string `header:"Location" doc:"URI of the created resource"`
ETag string `header:"ETag" doc:"Entity tag for caching and conditional requests"`
}
CreateUserOutput is the response for creating a user.
type DefaultAuthorizationHook ¶
type DefaultAuthorizationHook struct{}
DefaultAuthorizationHook is a no-op authorization hook that allows all operations.
func (DefaultAuthorizationHook) CanCreate ¶
func (DefaultAuthorizationHook) CanCreate(ctx context.Context, resourceType string) error
CanCreate always allows create operations.
func (DefaultAuthorizationHook) CanDelete ¶
func (DefaultAuthorizationHook) CanDelete(ctx context.Context, resourceType, resourceID string) error
CanDelete always allows delete operations.
type DeleteResourceInput ¶
type DeleteResourceInput struct {
ID string `path:"id" doc:"Resource ID"`
}
DeleteResourceInput contains parameters for deleting a resource.
type EnterpriseUser ¶
type EnterpriseUser struct {
EmployeeNumber string `json:"employeeNumber,omitempty"`
CostCenter string `json:"costCenter,omitempty"`
Organization string `json:"organization,omitempty"`
Division string `json:"division,omitempty"`
Department string `json:"department,omitempty"`
Manager *ManagerRef `json:"manager,omitempty"`
}
EnterpriseUser represents the Enterprise User extension (RFC 7643 Section 4.3).
type Error ¶
type Error struct {
Schemas []string `json:"schemas"`
ScimType string `json:"scimType,omitempty"`
Detail string `json:"detail,omitempty"`
Status int `json:"status"`
}
Error represents a SCIM error response as defined in RFC 7644 Section 3.12.
func ErrBadRequest ¶
ErrBadRequest creates a 400 Bad Request error.
func ErrConflict ¶
ErrConflict creates a 409 Conflict error for uniqueness violations.
func ErrForbidden ¶
ErrForbidden creates a 403 Forbidden error.
func ErrInternal ¶
ErrInternal creates a 500 Internal Server Error.
func ErrInvalidFilter ¶
ErrInvalidFilter creates a 400 Bad Request error for invalid filters.
func ErrInvalidPath ¶
ErrInvalidPath creates a 400 Bad Request error for invalid attribute paths.
func ErrInvalidSyntax ¶
ErrInvalidSyntax creates a 400 Bad Request error for invalid request syntax.
func ErrInvalidValue ¶
ErrInvalidValue creates a 400 Bad Request error for invalid values.
func ErrMutability ¶
ErrMutability creates a 400 Bad Request error for immutable attribute modifications.
func ErrNoTarget ¶
ErrNoTarget creates a 400 Bad Request error when PATCH target is not found.
func ErrNotFound ¶
ErrNotFound creates a 404 Not Found error.
func ErrNotImplemented ¶
ErrNotImplemented creates a 501 Not Implemented error.
func ErrPreconditionFailed ¶
ErrPreconditionFailed creates a 412 Precondition Failed error for ETag mismatches.
func ErrTooMany ¶
ErrTooMany creates a 400 Bad Request error when too many resources would be returned.
func ErrUnauthorized ¶
ErrUnauthorized creates a 401 Unauthorized error.
func ToSCIMError ¶
ToSCIMError converts a standard error to a SCIM error. If the error is already a SCIM error, it is returned as-is. Otherwise, a 500 Internal Server Error is returned.
type GetGroupOutput ¶
type GetGroupOutput struct {
Body *Group
ETag string `header:"ETag" doc:"Entity tag for caching and conditional requests"`
}
GetGroupOutput is the response for getting a single group.
type GetResourceInput ¶
type GetResourceInput struct {
ID string `path:"id" doc:"Resource ID"`
Attributes string `query:"attributes" doc:"Comma-separated list of attributes to return"`
ExcludedAttributes string `query:"excludedAttributes" doc:"Comma-separated list of attributes to exclude"`
IfNoneMatch string `header:"If-None-Match" doc:"ETag for conditional request"`
}
GetResourceInput contains parameters for getting a single resource.
func (*GetResourceInput) ToAttributeFilter ¶
func (i *GetResourceInput) ToAttributeFilter() *AttributeFilter
ToAttributeFilter creates an AttributeFilter from the input parameters.
type GetResourceTypeOutput ¶
type GetResourceTypeOutput struct {
Body *schema.ResourceType
}
GetResourceTypeOutput is the response for getting a single resource type.
type GetSchemaOutput ¶
GetSchemaOutput is the response for getting a single schema.
type GetUserOutput ¶
type GetUserOutput struct {
Body *User
ETag string `header:"ETag" doc:"Entity tag for caching and conditional requests"`
}
GetUserOutput is the response for getting a single user.
type Group ¶
type Group struct {
Resource
DisplayName string `json:"displayName"`
Members []MemberRef `json:"members,omitempty"`
}
Group represents a SCIM Group resource as defined in RFC 7643 Section 4.2.
type GroupRef ¶
type GroupRef struct {
Value string `json:"value,omitempty"`
Ref string `json:"$ref,omitempty"`
Display string `json:"display,omitempty"`
Type string `json:"type,omitempty"`
}
GroupRef represents a reference to a group in a user's groups attribute.
type ListGroupsOutput ¶
type ListGroupsOutput struct {
Body *ListResponse
}
ListGroupsOutput is the response for listing groups.
type ListOptions ¶
type ListOptions struct {
Filter string
StartIndex int
Count int
SortBy string
SortOrder string
Attributes []string
}
ListOptions contains parameters for list operations.
func DefaultListOptions ¶
func DefaultListOptions() ListOptions
DefaultListOptions returns sensible defaults for list operations.
type ListResourceTypesOutput ¶
type ListResourceTypesOutput struct {
Body *ListResponse
}
ListResourceTypesOutput is the response for listing resource types.
type ListResourcesInput ¶
type ListResourcesInput struct {
Filter string `query:"filter" doc:"SCIM filter expression (RFC 7644)"`
Attributes string `query:"attributes" doc:"Comma-separated list of attributes to return"`
ExcludedAttributes string `query:"excludedAttributes" doc:"Comma-separated list of attributes to exclude"`
SortBy string `query:"sortBy" doc:"Attribute path to sort by"`
SortOrder string `query:"sortOrder" enum:"ascending,descending" default:"ascending" doc:"Sort order"`
StartIndex int `query:"startIndex" minimum:"1" default:"1" doc:"1-based index of first result"`
Count int `query:"count" minimum:"0" doc:"Number of resources to return per page"`
}
ListResourcesInput contains common query parameters for list operations.
func (*ListResourcesInput) ToAttributeFilter ¶
func (i *ListResourcesInput) ToAttributeFilter() *AttributeFilter
ToAttributeFilter creates an AttributeFilter from the input parameters.
func (*ListResourcesInput) ToListOptions ¶
func (i *ListResourcesInput) ToListOptions(defaultCount int) ListOptions
ToListOptions converts input parameters to ListOptions.
type ListResponse ¶
type ListResponse struct {
Schemas []string `json:"schemas"`
TotalResults int `json:"totalResults"`
StartIndex int `json:"startIndex,omitempty"`
ItemsPerPage int `json:"itemsPerPage,omitempty"`
Resources []any `json:"Resources,omitempty"`
}
ListResponse represents a SCIM list response as defined in RFC 7644 Section 3.4.2.
func NewListResponse ¶
func NewListResponse(resources []any, totalResults, startIndex, itemsPerPage int) *ListResponse
NewListResponse creates a new ListResponse with the proper schema.
type ListSchemasOutput ¶
type ListSchemasOutput struct {
Body *ListResponse
}
ListSchemasOutput is the response for listing schemas.
type ListUsersOutput ¶
type ListUsersOutput struct {
Body *ListResponse
}
ListUsersOutput is the response for listing users.
type ManagerRef ¶
type ManagerRef struct {
Value string `json:"value,omitempty"`
Ref string `json:"$ref,omitempty"`
DisplayName string `json:"displayName,omitempty"`
}
ManagerRef represents a reference to a user's manager.
type MeOutput ¶
type MeOutput struct {
Body *User
ETag string `header:"ETag" doc:"Entity tag for caching and conditional requests"`
}
MeOutput is the response for /Me endpoint.
type MePatchInput ¶
type MePatchInput struct {
IfMatch string `header:"If-Match" doc:"ETag for conditional update"`
Body *PatchRequest `doc:"PATCH operations to apply"`
}
MePatchInput contains parameters for patching the current user.
type MemberRef ¶
type MemberRef struct {
Value string `json:"value,omitempty"`
Ref string `json:"$ref,omitempty"`
Display string `json:"display,omitempty"`
Type string `json:"type,omitempty"`
}
MemberRef represents a reference to a member in a group's members attribute.
type Meta ¶
type Meta struct {
ResourceType string `json:"resourceType,omitempty"`
Created *time.Time `json:"created,omitempty"`
LastModified *time.Time `json:"lastModified,omitempty"`
Location string `json:"location,omitempty"`
Version string `json:"version,omitempty"`
}
Meta contains resource metadata as defined in RFC 7643 Section 3.1.
type MultiValue ¶
type MultiValue struct {
Value string `json:"value,omitempty"`
Display string `json:"display,omitempty"`
Type string `json:"type,omitempty"`
Primary bool `json:"primary,omitempty"`
}
MultiValue represents a multi-valued attribute with metadata. Used for emails, phone numbers, addresses, etc.
type Name ¶
type Name struct {
Formatted string `json:"formatted,omitempty"`
FamilyName string `json:"familyName,omitempty"`
GivenName string `json:"givenName,omitempty"`
MiddleName string `json:"middleName,omitempty"`
HonorificPrefix string `json:"honorificPrefix,omitempty"`
HonorificSuffix string `json:"honorificSuffix,omitempty"`
}
Name represents a user's name components.
type NoOpHasher ¶
type NoOpHasher struct{}
NoOpHasher is a PasswordHasher that does not hash passwords. This is useful for testing or when passwords are hashed elsewhere.
func (*NoOpHasher) Hash ¶
func (h *NoOpHasher) Hash(password string) (string, error)
Hash returns the password as-is.
func (*NoOpHasher) Verify ¶
func (h *NoOpHasher) Verify(password, hash string) error
Verify compares passwords directly.
type Option ¶
type Option func(*API)
Option configures an API.
func WithLogger ¶
WithLogger sets the logger for the API. If not set, slog.Default() is used.
type PasswordHasher ¶
type PasswordHasher interface {
// Hash hashes a plain text password.
Hash(password string) (string, error)
// Verify compares a plain text password with a hashed password.
Verify(password, hash string) error
}
PasswordHasher defines the interface for password hashing operations.
func DefaultPasswordHasher ¶
func DefaultPasswordHasher() PasswordHasher
DefaultPasswordHasher returns the default password hasher (bcrypt).
type PatchOperation ¶
type PatchOperation struct {
Op string `json:"op"`
Path string `json:"path,omitempty"`
Value any `json:"value,omitempty"`
}
PatchOperation represents a single PATCH operation.
type PatchRequest ¶
type PatchRequest struct {
Schemas []string `json:"schemas"`
Operations []PatchOperation `json:"Operations"`
}
PatchRequest represents a SCIM PATCH request as defined in RFC 7644 Section 3.5.2.
type PatchResourceInput ¶
type PatchResourceInput struct {
ID string `path:"id" doc:"Resource ID"`
IfMatch string `header:"If-Match" doc:"ETag for conditional update"`
Body *PatchRequest `doc:"PATCH operations to apply"`
}
PatchResourceInput contains parameters for patching a resource.
type Provider ¶
type Provider struct {
// contains filtered or unexported fields
}
Provider is the main entry point for SCIM operations. It wraps a Store implementation and provides the Service interface.
func NewProvider ¶
func NewProvider(config *Config, store Store, opts ...ProviderOption) (*Provider, error)
NewProvider creates a new SCIM provider.
func (*Provider) PasswordHasher ¶
func (p *Provider) PasswordHasher() PasswordHasher
PasswordHasher returns the configured password hasher.
func (*Provider) ResourceTypes ¶
func (p *Provider) ResourceTypes() []schema.ResourceType
ResourceTypes returns all supported resource types.
func (*Provider) ServiceProviderConfig ¶
func (p *Provider) ServiceProviderConfig() schema.ServiceProviderConfig
ServiceProviderConfig returns the SCIM service provider configuration.
type ProviderOption ¶
type ProviderOption func(*Provider)
ProviderOption configures a Provider.
func WithAuthorizationHook ¶
func WithAuthorizationHook(hook AuthorizationHook) ProviderOption
WithAuthorizationHook sets a custom authorization hook.
func WithPasswordHasher ¶
func WithPasswordHasher(hasher PasswordHasher) ProviderOption
WithPasswordHasher sets a custom password hasher.
type RequestMetadata ¶
type RequestMetadata struct {
// Filter is the SCIM filter expression.
Filter string
// StartIndex is the 1-based index of the first result (default 1).
StartIndex int
// Count is the number of resources to return per page.
Count int
// SortBy is the attribute to sort by.
SortBy string
// SortOrder is "ascending" or "descending".
SortOrder string
// Attributes specifies which attributes to return.
Attributes []string
// ExcludedAttributes specifies which attributes to exclude.
ExcludedAttributes []string
// IfMatch is the ETag value from If-Match header.
IfMatch string
// IfNoneMatch is the ETag value from If-None-Match header.
IfNoneMatch string
}
RequestMetadata contains metadata extracted from a SCIM request.
func ExtractRequestMetadata ¶
func ExtractRequestMetadata(r *http.Request) RequestMetadata
ExtractRequestMetadata extracts SCIM request metadata from an HTTP request.
func (RequestMetadata) ToListOptions ¶
func (m RequestMetadata) ToListOptions(defaultCount int) ListOptions
ToListOptions converts RequestMetadata to ListOptions.
type Resource ¶
type Resource struct {
Schemas []string `json:"schemas"`
ID string `json:"id,omitempty"`
ExternalID string `json:"externalId,omitempty"`
Meta *Meta `json:"meta,omitempty"`
}
Resource is the base type for all SCIM resources.
type ResourceTypeNameInput ¶
type ResourceTypeNameInput struct {
Name string `path:"name" doc:"Resource type name"`
}
ResourceTypeNameInput contains the resource type name path parameter.
type RoleBasedAuthorizationHook ¶
type RoleBasedAuthorizationHook struct {
// AdminRoles are roles that have full SCIM access.
AdminRoles []string
// ReadOnlyRoles are roles that have read-only SCIM access.
ReadOnlyRoles []string
// RoleExtractor extracts roles from context.
// If nil, defaults to looking for "roles" in context values.
RoleExtractor func(ctx context.Context) []string
}
RoleBasedAuthorizationHook implements AuthorizationHook using role-based access. It checks that the authenticated user has an appropriate role for the operation.
func NewRoleBasedAuthorizationHook ¶
func NewRoleBasedAuthorizationHook(adminRoles, readOnlyRoles []string) *RoleBasedAuthorizationHook
NewRoleBasedAuthorizationHook creates a new role-based authorization hook.
func (*RoleBasedAuthorizationHook) CanCreate ¶
func (h *RoleBasedAuthorizationHook) CanCreate(ctx context.Context, resourceType string) error
CanCreate checks if the authenticated user can create resources of this type.
func (*RoleBasedAuthorizationHook) CanDelete ¶
func (h *RoleBasedAuthorizationHook) CanDelete(ctx context.Context, resourceType, resourceID string) error
CanDelete checks if the authenticated user can delete the resource.
type SchemaIDInput ¶
type SchemaIDInput struct {
ID string `path:"id" doc:"Schema URN"`
}
SchemaIDInput contains the schema ID path parameter.
type ScopedAuthorizationHook ¶
type ScopedAuthorizationHook struct {
// RequireScopes determines whether to enforce scope checking.
// If false, all operations are allowed (useful for development/testing).
RequireScopes bool
}
ScopedAuthorizationHook implements AuthorizationHook using OAuth scopes. It checks that the request context contains appropriate scopes for the operation.
func NewScopedAuthorizationHook ¶
func NewScopedAuthorizationHook(requireScopes bool) *ScopedAuthorizationHook
NewScopedAuthorizationHook creates a new scoped authorization hook.
func (*ScopedAuthorizationHook) CanCreate ¶
func (h *ScopedAuthorizationHook) CanCreate(ctx context.Context, resourceType string) error
CanCreate checks if the authenticated user can create resources of this type.
func (*ScopedAuthorizationHook) CanDelete ¶
func (h *ScopedAuthorizationHook) CanDelete(ctx context.Context, resourceType, resourceID string) error
CanDelete checks if the authenticated user can delete the resource.
type SearchInput ¶
type SearchInput struct {
Body *SearchRequest `doc:"Search request body"`
}
SearchInput contains the request body for a search operation.
type SearchOutput ¶
type SearchOutput struct {
Body *ListResponse
}
SearchOutput is the response for search operations.
type SearchRequest ¶
type SearchRequest struct {
Schemas []string `json:"schemas,omitempty"`
Attributes []string `json:"attributes,omitempty"`
ExcludedAttributes []string `json:"excludedAttributes,omitempty"`
Filter string `json:"filter,omitempty"`
SortBy string `json:"sortBy,omitempty"`
SortOrder string `json:"sortOrder,omitempty"`
StartIndex int `json:"startIndex,omitempty"`
Count int `json:"count,omitempty"`
}
SearchRequest represents a SCIM search request body (POST /.search).
func (*SearchRequest) ToAttributeFilter ¶
func (s *SearchRequest) ToAttributeFilter() *AttributeFilter
ToAttributeFilter creates an AttributeFilter from the search request.
func (*SearchRequest) ToListOptions ¶
func (s *SearchRequest) ToListOptions(defaultCount int) ListOptions
ToListOptions converts a SearchRequest to ListOptions.
type Service ¶
type Service interface {
// GetUser retrieves a user by ID.
GetUser(ctx context.Context, id string) (*User, error)
// ListUsers lists users with optional filtering and pagination.
ListUsers(ctx context.Context, opts ListOptions) (*ListResponse, error)
// CreateUser creates a new user.
CreateUser(ctx context.Context, user *User) (*User, error)
// UpdateUser replaces a user (PUT semantics).
UpdateUser(ctx context.Context, id string, user *User, etag string) (*User, error)
// PatchUser applies partial modifications to a user.
PatchUser(ctx context.Context, id string, patch *PatchRequest, etag string) (*User, error)
// DeleteUser removes a user.
DeleteUser(ctx context.Context, id string) error
// GetGroup retrieves a group by ID.
GetGroup(ctx context.Context, id string) (*Group, error)
// ListGroups lists groups with optional filtering and pagination.
ListGroups(ctx context.Context, opts ListOptions) (*ListResponse, error)
// CreateGroup creates a new group.
CreateGroup(ctx context.Context, group *Group) (*Group, error)
// UpdateGroup replaces a group (PUT semantics).
UpdateGroup(ctx context.Context, id string, group *Group, etag string) (*Group, error)
// PatchGroup applies partial modifications to a group.
PatchGroup(ctx context.Context, id string, patch *PatchRequest, etag string) (*Group, error)
// DeleteGroup removes a group.
DeleteGroup(ctx context.Context, id string) error
// ProcessBulk processes a bulk request.
ProcessBulk(ctx context.Context, req *BulkRequest) (*BulkResponse, error)
// GetMe retrieves the current user based on context.
GetMe(ctx context.Context) (*User, error)
// PatchMe applies partial modifications to the current user.
PatchMe(ctx context.Context, patch *PatchRequest, etag string) (*User, error)
}
Service defines the SCIM service interface for managing users and groups.
type ServiceProviderConfigOutput ¶
type ServiceProviderConfigOutput struct {
Body schema.ServiceProviderConfig
}
ServiceProviderConfigOutput is the response for the ServiceProviderConfig endpoint.
type Store ¶
type Store interface {
// GetUserByID retrieves a user by SCIM ID.
GetUserByID(ctx context.Context, id string) (*User, error)
// GetUserByUserName retrieves a user by userName (typically email).
GetUserByUserName(ctx context.Context, userName string) (*User, error)
// GetUserByExternalID retrieves a user by externalId.
GetUserByExternalID(ctx context.Context, externalID string) (*User, error)
// ListUsers lists users with filtering and pagination.
// Returns resources, total count, and error.
ListUsers(ctx context.Context, opts ListOptions) ([]*User, int, error)
// CreateUser creates a new user.
CreateUser(ctx context.Context, user *User) (*User, error)
// UpdateUser updates an existing user.
UpdateUser(ctx context.Context, id string, user *User) (*User, error)
// DeleteUser deletes a user.
DeleteUser(ctx context.Context, id string) error
// GetGroupByID retrieves a group by SCIM ID.
GetGroupByID(ctx context.Context, id string) (*Group, error)
// GetGroupByDisplayName retrieves a group by displayName.
GetGroupByDisplayName(ctx context.Context, displayName string) (*Group, error)
// GetGroupByExternalID retrieves a group by externalId.
GetGroupByExternalID(ctx context.Context, externalID string) (*Group, error)
// ListGroups lists groups with filtering and pagination.
// Returns resources, total count, and error.
ListGroups(ctx context.Context, opts ListOptions) ([]*Group, int, error)
// CreateGroup creates a new group.
CreateGroup(ctx context.Context, group *Group) (*Group, error)
// UpdateGroup updates an existing group.
UpdateGroup(ctx context.Context, id string, group *Group) (*Group, error)
// DeleteGroup deletes a group.
DeleteGroup(ctx context.Context, id string) error
// GetGroupsForUser returns all groups a user belongs to.
GetGroupsForUser(ctx context.Context, userID string) ([]GroupRef, error)
// GetMembersForGroup returns all members of a group.
GetMembersForGroup(ctx context.Context, groupID string) ([]MemberRef, error)
// AddMemberToGroup adds a user to a group.
AddMemberToGroup(ctx context.Context, groupID, userID string) error
// RemoveMemberFromGroup removes a user from a group.
RemoveMemberFromGroup(ctx context.Context, groupID, userID string) error
}
Store defines the persistence layer interface for SCIM resources. Implementations map SCIM operations to the underlying data store.
type UpdateGroupInput ¶
type UpdateGroupInput struct {
ID string `path:"id" doc:"Group ID"`
IfMatch string `header:"If-Match" doc:"ETag for conditional update"`
Body *Group `doc:"Group resource to replace"`
}
UpdateGroupInput contains parameters for replacing a group.
type UpdateGroupOutput ¶
type UpdateGroupOutput struct {
Body *Group
ETag string `header:"ETag" doc:"Entity tag for caching and conditional requests"`
}
UpdateGroupOutput is the response for updating a group.
type UpdateUserInput ¶
type UpdateUserInput struct {
ID string `path:"id" doc:"User ID"`
IfMatch string `header:"If-Match" doc:"ETag for conditional update"`
Body *User `doc:"User resource to replace"`
}
UpdateUserInput contains parameters for replacing a user.
type UpdateUserOutput ¶
type UpdateUserOutput struct {
Body *User
ETag string `header:"ETag" doc:"Entity tag for caching and conditional requests"`
}
UpdateUserOutput is the response for updating a user.
type User ¶
type User struct {
Resource
UserName string `json:"userName"`
Name *Name `json:"name,omitempty"`
DisplayName string `json:"displayName,omitempty"`
NickName string `json:"nickName,omitempty"`
ProfileURL string `json:"profileUrl,omitempty"`
Title string `json:"title,omitempty"`
UserType string `json:"userType,omitempty"`
PreferredLanguage string `json:"preferredLanguage,omitempty"`
Locale string `json:"locale,omitempty"`
Timezone string `json:"timezone,omitempty"`
Active *bool `json:"active,omitempty"`
Password string `json:"password,omitempty"` //nolint:gosec // G117: field holds SCIM password attribute, not hardcoded secret
Emails []MultiValue `json:"emails,omitempty"`
PhoneNumbers []MultiValue `json:"phoneNumbers,omitempty"`
IMs []MultiValue `json:"ims,omitempty"`
Photos []MultiValue `json:"photos,omitempty"`
Addresses []Address `json:"addresses,omitempty"`
Groups []GroupRef `json:"groups,omitempty"`
Entitlements []MultiValue `json:"entitlements,omitempty"`
Roles []MultiValue `json:"roles,omitempty"`
X509Certificates []MultiValue `json:"x509Certificates,omitempty"`
// Enterprise User Extension
EnterpriseUser *EnterpriseUser `json:"urn:ietf:params:scim:schemas:extension:enterprise:2.0:User,omitempty"`
}
User represents a SCIM User resource as defined in RFC 7643 Section 4.1.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package filter provides SCIM filter expression parsing and evaluation.
|
Package filter provides SCIM filter expression parsing and evaluation. |
|
Package mapper provides mapping between SCIM resources and CoreForge entities.
|
Package mapper provides mapping between SCIM resources and CoreForge entities. |
|
Package patch provides SCIM PATCH operation handling.
|
Package patch provides SCIM PATCH operation handling. |
|
Package schema provides SCIM schema definitions for discovery endpoints.
|
Package schema provides SCIM schema definitions for discovery endpoints. |
|
Package store provides SCIM Store implementations.
|
Package store provides SCIM Store implementations. |