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 WithPlatformScope(ctx context.Context) context.Context
- func WithRequestID(ctx context.Context, requestID string) context.Context
- func WithRoles(ctx context.Context, roles []string) context.Context
- func WithScope(ctx context.Context, scope Scope) context.Context
- func WithTenant(ctx context.Context, orgID uuid.UUID) 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) CredentialMiddleware(authFn func(r *http.Request) (Credential, error)) func(http.Handler) http.Handler
- 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.Handlerdeprecated
- func (a *API) Provider() *Provider
- func (a *API) Router() chi.Router
- func (a *API) ServeHTTP(w http.ResponseWriter, r *http.Request)
- type Address
- type AllowAllAuthorizationHook
- 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 Credential
- type DefaultAuthorizationHookdeprecated
- 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 DenyAllAuthorizationHook
- func (DenyAllAuthorizationHook) CanCreate(context.Context, string) error
- func (DenyAllAuthorizationHook) CanDelete(context.Context, string, string) error
- func (DenyAllAuthorizationHook) CanRead(context.Context, string, string) error
- func (DenyAllAuthorizationHook) CanUpdate(context.Context, string, string) error
- 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 Scope
- 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 WithPlatformScope ¶ added in v0.20.0
WithPlatformScope binds the request to every organization. Use it only for platform operator credentials.
func WithRequestID ¶
WithRequestID adds a request ID to the context.
func WithScope ¶ added in v0.20.0
WithScope binds the request to a provisioning scope. Stores refuse requests without a valid scope.
func WithTenant ¶ added in v0.20.0
WithTenant binds the request to one organization.
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) CredentialMiddleware ¶ added in v0.20.0
func (a *API) CredentialMiddleware(authFn func(r *http.Request) (Credential, error)) func(http.Handler) http.Handler
CredentialMiddleware returns HTTP middleware for SCIM authentication. authFn validates the request and returns its credential, which must be bound to one organization or, for platform operators, to the platform.
func (*API) Middleware
deprecated
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.
Deprecated: Middleware binds no provisioning scope, so stores refuse its requests. Use CredentialMiddleware.
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 AllowAllAuthorizationHook ¶ added in v0.14.0
type AllowAllAuthorizationHook = DefaultAuthorizationHook
AllowAllAuthorizationHook allows every operation. Use it only when the API is protected another way, such as authentication middleware that admits only the identity provider; it is for tests and development otherwise.
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 Credential ¶ added in v0.20.0
type Credential struct {
// Subject identifies the client (for example a token ID).
Subject string
// Scopes are the client's SCIM scopes (ScopeUsersRead, ...).
Scopes []string
// Scope is what the client may provision: its organization, or the
// platform for an operator credential. Requests with an invalid scope
// are refused.
Scope Scope
}
Credential is an authenticated SCIM client.
type DefaultAuthorizationHook
deprecated
type DefaultAuthorizationHook struct{}
DefaultAuthorizationHook is a no-op authorization hook that allows all operations.
Deprecated: despite the name it is not the provider's default any more (that is DenyAllAuthorizationHook); use AllowAllAuthorizationHook to allow everything explicitly.
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 DenyAllAuthorizationHook ¶ added in v0.14.0
type DenyAllAuthorizationHook struct{}
DenyAllAuthorizationHook refuses every operation. It is the provider's default, so a SCIM API mounted without an authorization hook exposes nothing.
func (DenyAllAuthorizationHook) CanCreate ¶ added in v0.14.0
func (DenyAllAuthorizationHook) CanCreate(context.Context, string) error
CanCreate always refuses.
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 Scope ¶ added in v0.20.0
type Scope struct {
// OrganizationID is the organization a tenant credential provisions.
OrganizationID uuid.UUID
// Platform marks a platform operator credential that provisions every
// organization.
Platform bool
}
Scope is what a SCIM credential may provision: one organization (a tenant's identity provider) or, for an explicitly marked platform operator credential, every organization.
func ScopeFromContext ¶ added in v0.20.0
ScopeFromContext returns the request's provisioning scope.
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 SystemForge entities.
|
Package mapper provides mapping between SCIM resources and SystemForge 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. |