Documentation
¶
Overview ¶
Package scim is the suite's SCIM 2.0 client (RFC 7643, RFC 7644) and the wire types it shares with a server. KySignOn provisions accounts into downstream products and third-party SCIM servers; before this package its resource types, paths and status handling were inlined in its sync engine, where a 409 on create counted as a delivered account, paths were built from local IDs the server had never issued, and generic targets got the suite signature in place of their bearer token. Each of those leaves an account that does not exist recorded as provisioned, which is the bar for a primitive living here.
Users only. Groups, listing and bulk are not built because nothing in the suite sends them.
Index ¶
- Constants
- Variables
- type Client
- func (c *Client) CreateUser(ctx context.Context, user User) (User, error)
- func (c *Client) DeleteUser(ctx context.Context, id string) error
- func (c *Client) FindUser(ctx context.Context, attribute, value string) (User, error)
- func (c *Client) GetUser(ctx context.Context, id string) (User, error)
- func (c *Client) PatchUser(ctx context.Context, id string, ops ...PatchOperation) (User, error)
- func (c *Client) Ping(ctx context.Context) error
- func (c *Client) ReplaceUser(ctx context.Context, id string, user User) (User, error)
- type Error
- type Meta
- type MultiValue
- type Name
- type PatchOperation
- type User
Constants ¶
const ( UserSchema = "urn:ietf:params:scim:schemas:core:2.0:User" PatchOpSchema = "urn:ietf:params:scim:api:messages:2.0:PatchOp" ListResponseSchema = "urn:ietf:params:scim:api:messages:2.0:ListResponse" ErrorSchema = "urn:ietf:params:scim:api:messages:2.0:Error" )
Variables ¶
var ( // ErrNotFound is a 404: the resource is not there. On a delete the caller decides // whether "already gone" is the outcome it wanted. ErrNotFound = errors.New("scim: resource not found") // ErrConflict is a 409: the server refused a create as a duplicate. It is never success; // look the account up by externalId or userName and reconcile. ErrConflict = errors.New("scim: conflict") ErrUnauthorized = errors.New("scim: unauthorized") // ErrThrottled is a 429 or 503; Error.RetryAfter carries the server's hint when it sent one. ErrThrottled = errors.New("scim: throttled") // ErrAmbiguous means a filter that should identify one user matched more than one. ErrAmbiguous = errors.New("scim: filter matched more than one user") // ErrMalformedResponse means a 2xx whose body is not the resource it should be, is // larger than the client will read, or lacks the id a create must return. ErrMalformedResponse = errors.New("scim: malformed response") // ErrInsecureURL means BaseURL is not an HTTPS URL with a host and nothing else. ErrInsecureURL = errors.New("scim: base URL must be https with a host and no credentials, query or fragment") // ErrNoToken means Token is empty. ErrNoToken = errors.New("scim: bearer token is required") )
Functions ¶
This section is empty.
Types ¶
type Client ¶
type Client struct {
// BaseURL is the SCIM root, e.g. https://host/scim/v2. HTTPS only.
BaseURL string
// Token is sent as Authorization: Bearer and nowhere else.
Token string
HTTPClient *http.Client
}
Client talks to one SCIM server. The zero HTTPClient is a ten-second client; products with an outbound policy (private-range refusal, dial guards) pass their own. Redirects are refused whatever client is passed.
func (*Client) CreateUser ¶
CreateUser POSTs the user and returns the resource the server minted. The returned ID is the handle for every later call; the caller's ID and Meta are not sent. A 409 is ErrConflict, never success.
func (*Client) DeleteUser ¶
DeleteUser removes the user. A 404 is ErrNotFound; whether that is fine is the caller's call.
func (*Client) FindUser ¶
FindUser looks a user up by an equality filter on "externalId" or "userName", the two attributes the result can be checked against. Zero matches is ErrNotFound; more than one is ErrAmbiguous; one that does not carry the value is ErrMalformedResponse, because a server without filtering returns its collection, and one unrelated user in it must not become the account that is deactivated next.
func (*Client) PatchUser ¶
PatchUser applies operations, e.g. {Op: "replace", Path: "active", Value: false} to deprovision. The returned User is zero when the server answers 204.
type Error ¶
type Error struct {
Status int
ScimType string
Detail string
// RetryAfter is the server's Retry-After hint, zero when absent, capped at one hour.
RetryAfter time.Duration
}
Error is a non-2xx response. Detail is the server's text with the bearer token redacted, made printable and cut short, so it can reach a log or an audit record as it is.
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 is the server-owned resource metadata.
type MultiValue ¶
type MultiValue struct {
Value string `json:"value"`
Type string `json:"type,omitempty"`
Display string `json:"display,omitempty"`
Primary bool `json:"primary,omitempty"`
}
MultiValue is one entry of a multi-valued attribute such as emails or roles.
type Name ¶
type Name struct {
Formatted string `json:"formatted,omitempty"`
GivenName string `json:"givenName,omitempty"`
FamilyName string `json:"familyName,omitempty"`
}
Name is the User's name complex attribute.
type PatchOperation ¶
type PatchOperation struct {
Op string `json:"op"`
Path string `json:"path,omitempty"`
Value any `json:"value,omitempty"`
}
PatchOperation is one entry of a PatchOp's Operations. Value is omitted when nil, which is what a remove wants.
type User ¶
type User struct {
Schemas []string `json:"schemas"`
ID string `json:"id,omitempty"`
ExternalID string `json:"externalId,omitempty"`
UserName string `json:"userName"`
DisplayName string `json:"displayName,omitempty"`
Name *Name `json:"name,omitempty"`
Emails []MultiValue `json:"emails,omitempty"`
Roles []MultiValue `json:"roles,omitempty"`
Active bool `json:"active"`
Meta *Meta `json:"meta,omitempty"`
}
User is the core User resource with the attributes the suite exchanges. The server owns ID and Meta; the client never sends them.