h$WUIL      !"#$%&'()*+,-./0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~                                                  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"""## Safe-Inferred -/58>? zNone -/58>? hscimAn attribute (e.g. username).ATTRNAME = ALPHA *(nameChar) NOTE: We use the FromJSONKey instance of Text. The default instances parses a list of key values instead of a maphscimAttribute name parser.hscimAttribute name renderer.None -/58>?   None -/58>? O  None -/58>?   None -/58>? None -/58>? None -/58>?FNone -/58<>? hscim,Turn all keys in a JSON object to lowercase. !" !" None -/58>?x0hscimThe way authentication schemes are expected to be represented in the configuration. Each 1' corresponds to one of such encodings.1hscimPossible authentication schemes. The specification defines the values "oauth", "oauth2", "oauthbearertoken", "httpbasic", and "httpdigest".7hscimThe description of the 5 scheme.0123456712345607 None -/58>?wAhscimAll schemas that we support.KhscimGet schema URI (e.g. *urn:ietf:params:scim:schemas:core:2.0:User).LhscimParser for schemasNOTE: according to the spec, this parser needs to be case insensitive, but that is literally insane. Won't implement.MhscimGet a schema by its URI.0NOTE: case sensitive against the spec. Same as L.TODO(arianvp): probably too lenient. want to only accept valid URNs This means the CustomSchema part might go... We need to kind of rethink how we're gonna do extensions anyway, as we're gonna have to support multiple extensions, which is currently a bit iffy I thinkNhscimGet schema description as JSON.AHGFEDCJIBKLMNAHGFEDCJIBKLMN None -/58>?Shscim&Definitions of endpoints, returned by /ResourceTypes.XhscimSupported resource types. Each resource type also corresponds to an endpoint, described by ResourceTypeEndpoint. STVWUXZY[\ XZYSTVWU[\ None -/58>?ohscimResource version:  0https://tools.ietf.org/html/rfc7644#section-3.14.A version is an opaque string that doesn't need to conform to any format (e.g. it does not have to be a monotonically increasing integer, contrary to what the word version suggests).For r versions we have to guarantee that different resources will have different os. For s versions we also have to guarantee that same resources will have the same o.fgihjknmlpoqsrqsrjknmlpofgih None #$-/58>?hscimA "pagination" type used as a wrapper whenever a SCIM endpoint has to return a list.Pagination is not actually supported anywhere in the code yet; whenever there are several results we always return them all as one page, and we don't support different values of .FUTUREWORK: Support for pagination might be added once we have to handle organizations with lots of users.None -/58>?*hscimAn ADT for error types in the SCIM specification. Not all possible SCIM errors have a corresponding < (for instance, authorization is not covered by this type).See +https://tools.ietf.org/html/rfc7644#page-69hscimConvert a SCIM Error? to a Servant one by encoding it with the appropriate headers.hscim Error typehscim Error detailshscim Error detailshscim Error detailshscim Resource typehscim Resource IDhscim Error detailsNone -/58>?hscim5Handler type for SCIM. All errors will be thrown via .hscimThrow a .hscimA natural transformation for Servant handlers. To use it, you need to provide a way to throw errors in the underlying m monad.We can't use something like  to throw errors in m because . allows only one type of errors per monad and m might have one already.'You can either do something custom for  , or use scimToServantErr.None -/58>? hscimAn interface that has to be implemented for a server to provide authentication.hscim'Do authentication or throw an error in  (e.g. $) if the provided credentials are invalid or don't correspond to any user.hscim&Types used in authentication routines.hscimThe type that the @Authorization@ header will be parsed as. This info will be given to .hscim(The result of performing authentication.Can be () to handle just authorized/non-authorized, or something more complex @ for instance, if the auth header provides a token that may or may not correspond to a particular organization, then the result could be the ID of that organization).None -/58>?$hscimGet all groups.hscimGet a single group by ID. Should throw notFound if the group does not.hscimCreate a new group. Should throw conflict( if uniqueness constraints are violated.hscimOverwrite an existing group. Should throw notFound" if the group does not exist, and conflict) if uniqueness constraints are violated.hscimModify an existing group. Should throw notFound! if the group doesn't exist, and conflict) if uniqueness constraints are violated.,FUTUREWORK: add types for PATCH (instead of ). See 1https://tools.ietf.org/html/rfc7644#section-3.5.2hscimDelete a group. Should throw notFound if the group does not exist.hscimConfigurable parts of .hscimGroup ID type.hscim PATCH payloadNone -/58>?-hscim'attrPath = [URI ":"] ATTRNAME *1subAtthscimsubAttr = "." ATTRNAMEhscimvaluePath = attrPath "[" valFilter "]" TODO(arianvp): This is a slight simplification at the moment as we don't support the complete Filter grammar. This should be a valFilter, not a FILTER.hscim A filter.Our representation of filters is lax and doesn't attempt to ensure validity on the type level. If a filter does something silly (e.g. tries to compare a username with a boolean), it will be caught during filtering and an appropriate error message will be thrown (see  filterUser).TODO(arianvp): Implement the following grammar fully if we want to support more complex filtersFILTER = attrExp  logExp # valuePath / *1"not" "(" FILTER ")"hscim*Compare the attribute value with a literalhscimA comparison operator.hscimEqualhscim Not equalhscimContainshscim Starts withhscim Ends withhscim Greater thanhscimGreater than or equal tohscim Less thanhscimLess than or equal tohscim=A value type. Attributes are compared against literal values.hscimSmart constructor that refers to a toplevel field with default schemahscim%PATH = attrPath / valuePath [subAttr]Currently we don't support matching on lists in paths as we currently don't support filtering on arbitrary attributes yet e.g.  "path":"members[value eq "2819c223-7f76-453a-919d-413861904646"].displayName"  is not supported?Parse a filter. Spaces surrounding the filter will be stripped.If parsing fails, returns a  with an error description.Note: this parser is written with Attoparsec because I don't know how to lift an Attoparsec parser (from Aeson) to Megaparsechscim ATTRNAME = ALPHA *(nameChar) attrPath = [URI ":"] ATTRNAME *1subAtt hscimsubAttr = "." ATTRNAMEhscim&valuePath = attrPath "[" valFilter "]"hscimFilter parser.hscim+Render a filter according to the SCIM spec.hscimComparison operator renderer.hscimExecute a comparison operator.hscim7We currently only support filtering on core user schema##None -/58>?.None -/58>?/\  None -/58>?/None -/58>?0 None -/58>?0eNone -/58>?0  None -/58>?1None -/58>?1ZNone -/58>?2hscimConfigurable parts of User.hscim User ID type.hscimExtra data carried with each User.hscimSchemas supported by the User for filtering and patching..This must include User20, this is not checked.None -/58>?5hscim1A very coarse description of what it means to be  I do not like it. We should handhold people using this library morehscim%PATH = attrPath / valuePath [subAttr]hscimThe  attribute value is a  containing an attribute path describing the target of the operation. It is OPTIONAL for s "add" and "replace", and is REQUIRED for "remove". See relevant operation sections below for details.TODO(arianvp): When value is an array, it needs special handling. e.g. primary fields need to be negated and whatnot. We currently do not do that :)NOTE: When the path contains a schema, this schema must be implicitly added to the list of schemas on the result typehscim%PATH = attrPath / valuePath [subAttr]None #$&'(-/258>?8hscimA type used to indicate that the SCIM record doesn't have any extra data. Encoded as an empty map.hscim3SCIM user record, parametrized with type-level tag t (see ).hscimApplies a JSON Patch to a SCIM Core User Only supports the core attributes. Evenmore, only some hand-picked ones currently. We'll have to think how patch is going to work in the presence of extensions. Also, we can probably make PatchOp type-safe to some extent (Read arianvp's thesis :))hscimSchemashscimuserNamehscim Extra data$None -/589>??<hscim(Get all users, optionally filtered by a .hscimGet a single user by ID. Should throw notFound if the user doesn't exist.hscimCreate a new user. Should throw conflict( if uniqueness constraints are violated.hscimOverwrite an existing user. Should throw notFound if the user doesn't exist, and conflict) if uniqueness constraints are violated.hscimModify an existing user. Should throw notFound if the user doesn't exist, and conflict) if uniqueness constraints are violated. 1https://tools.ietf.org/html/rfc7644#section-3.5.2If the target location already contains the value specified, no changes SHOULD be made to the resource, and a success response SHOULD be returned. Unless other operations change the resource, this operation SHALL NOT change the modify timestamp of the resource.Given that PUT has the same constraints, we can implement PATCH in terms of some magic in this library, GET and PUT.SCIM's Patch semantics are hard to get right. So we advice using the library built-in implementation. we implement PATCH in terms of a GET followed by a PUT. GET will retrieve the entire record; we then modify this record by a series of PATCH operations, and then PUT the entire record.hscimDelete a user. Should throw notFound if the user doesn't exist.hscim PATCH payloadNone -/58>??   None -/58>?BBhscimA simple ID type.#eitherDecode' @Id . encode $ (Id 3)Right (Id {unId = 3})=WARNING: {doctests don't work in our infrastructure](https:/ github.comzinfrabackend-issues7issues/1549), so this is duplicated in the unit tests.hscimTag used in the mock server.hscim*Check whether a user satisfies the filter.Returns  if the filter is constructed incorrectly (e.g. tries to compare a username with a boolean).TODO(arianvp): We need to generalise filtering at some point probably.!None #$-/58>?HZhscimA type-level tag for , =, etc. that allows picking any types we might need in tests.hscimA way to parse out a single value from a JSON object by specifying the field as a type-level string. Very useful when you don't want to create extra types.hscimsome acceptance tests match against a fully rendered response body, which will not work when running the test as a library user (since the response will have more and other information). if you leave this on  (default from ), the test will only check some invariants on the response instead that must hold in all cases.hscimre-implementation of  with better error reporting. FUTUREWORK: make this a PR upstream. (while we're at it, we can also patch  and  to keep track of the SRequest=, and add that to the error message here with the response.)hscimavoid multiple /. (kill at most one / at the end of first arg and beginning of second arg, resp., then add one during concatenation.<["a" "b", "a" "/b", "a/" "b", "a/" "/b"]["a/b","a/b","a/b","a/b"]=WARNING: {doctests don't work in our infrastructure](https:/ github.comzinfrabackend-issues7issues/1549), so this is duplicated in the unit tests.hscimA response matcher and quasiquoter that should be used instead of %&."None #$-/58>?I''()*+,-./0123456789::;<<=>>?@ABCDEFGHIJKLMNOPQR S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v v w x y z { | } ~                                                  $@@@@@@@w                                 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"""########"hscim-0.3.4-IDo0TEV7PyB1v1BS6PppD2Web.Scim.AttrName&Web.Scim.Capabilities.MetaSchema.Group-Web.Scim.Capabilities.MetaSchema.ResourceType)Web.Scim.Capabilities.MetaSchema.SPConfig'Web.Scim.Capabilities.MetaSchema.Schema%Web.Scim.Capabilities.MetaSchema.UserWeb.Scim.ContentTypeWeb.Scim.Schema.Common$Web.Scim.Schema.AuthenticationSchemeWeb.Scim.Schema.SchemaWeb.Scim.Schema.ResourceTypeWeb.Scim.Schema.MetaWeb.Scim.Schema.ListResponseWeb.Scim.Schema.ErrorWeb.Scim.HandlerWeb.Scim.Class.AuthWeb.Scim.Class.GroupWeb.Scim.Filter Web.Scim.Capabilities.MetaSchemaWeb.Scim.Schema.User.Address Web.Scim.Schema.User.CertificateWeb.Scim.Schema.User.EmailWeb.Scim.Schema.User.IMWeb.Scim.Schema.User.NameWeb.Scim.Schema.User.PhoneWeb.Scim.Schema.User.PhotoWeb.Scim.Schema.UserTypesWeb.Scim.Schema.PatchOpWeb.Scim.Schema.UserWeb.Scim.Class.UserWeb.Scim.ServerWeb.Scim.Server.MockWeb.Scim.Test.UtilWeb.Scim.Test.Acceptance Paths_hscim unauthorizedTest.Hspec.Wai.JSONjsonAttrName pAttrName rAttrName$fIsStringAttrName$fHashableAttrName $fOrdAttrName $fEqAttrName$fShowAttrName$fFromJSONKeyAttrName$fToJSONKeyAttrName groupSchemaresourceSchemaspConfigSchema metaSchema userSchemaSCIM$fMimeUnrenderTYPESCIMa$fMimeRenderTYPESCIMa$fAcceptTYPESCIMScimBool unScimBoolURIunURIWithIdidvalue toKeywordserializeOptions jsonLower fromKeyword parseOptions$fFromJSONWithId$fToJSONWithId $fToJSONURI $fFromJSONURI$fFromJSONScimBool $fEqScimBool$fShowScimBool $fOrdScimBool$fToJSONScimBool $fShowURI$fEqURI $fEqWithId $fShowWithIdAuthenticationSchemeEncodingAuthenticationScheme AuthOAuth AuthOAuth2AuthOAuthBearerToken AuthHttpBasicAuthHttpDigestauthHttpBasicEncoding$$fToJSONAuthenticationSchemeEncoding"$fShowAuthenticationSchemeEncoding $fEqAuthenticationSchemeEncoding%$fGenericAuthenticationSchemeEncoding$fEqAuthenticationScheme$fShowAuthenticationScheme$fEnumAuthenticationScheme$fBoundedAuthenticationScheme$fOrdAuthenticationSchemeSchemaUser20ServiceProviderConfig20Group20Schema20ResourceType20ListResponse20Error20 PatchOp20 CustomSchema getSchemaUripSchema fromSchemaUri getSchema$fToJSONSchema$fFromJSONSchema $fShowSchema $fEqSchemaResourcenameendpointschema ResourceType UserResource GroupResource usersResourcegroupsResource$fFromJSONResourceType$fToJSONResourceType$fFromJSONResource$fToJSONResource$fShowResource $fEqResource$fGenericResource$fShowResourceType$fEqResourceTypeWithMetametathingMeta resourceTypecreated lastModifiedversionlocationETagWeakStrong$fFromJSONETag $fToJSONETag$fFromJSONMeta $fToJSONMeta$fFromJSONWithMeta$fToJSONWithMeta $fEqWithMeta$fShowWithMeta$fGenericWithMeta$fEqMeta $fShowMeta $fGenericMeta$fEqETag $fShowETag ListResponseschemas totalResults itemsPerPage startIndex resourcesfromList$fToJSONListResponse$fFromJSONListResponse$fShowListResponse$fEqListResponse$fGenericListResponse ScimErrorstatusscimTypedetailStatusunStatus ScimErrorType InvalidFilterTooMany Uniqueness Mutability InvalidSyntax InvalidPathNoTarget InvalidValue InvalidVers Sensitive badRequest forbiddennotFoundconflict serverErrorscimToServerError$fToJSONScimErrorType$fToJSONStatus$fExceptionScimError$fToJSONScimError$fShowScimError $fEqScimError$fGenericScimError $fShowStatus $fEqStatus$fGenericStatus$fShowScimErrorType$fEqScimErrorType$fGenericScimErrorType ScimHandler throwScimfromScimHandlerAuthDB authCheck AuthTypesAuthDataAuthInfoGroupDB getGroupsgetGroup postGroupputGroup patchGroup deleteGroup GroupSite gsGetGroups gsGetGroup gsPostGroup gsPutGroup gsPatchGroup gsDeleteGroup StoredGroupGroup displayNamemembersMembertypref GroupTypesGroupId groupServer$fToJSONMember$fFromJSONMember $fToJSONGroup$fFromJSONGroup$fGenericGroupSite $fShowGroup $fEqGroup$fGenericGroup $fShowMember $fEqMember$fGenericMemberAttrPathSubAttr ValuePathFilterFilterAttrCompare CompareOpOpEqOpNeOpCoOpSwOpEwOpGtOpGeOpLtOpLe CompValueValNullValBool ValNumber ValStringtopLevelAttrPath parseFilter pAttrPathpSubAttr pValuePathpFilter renderFilter rAttrPathrSubAttr rValuePath rCompareOp compareStr$fToHttpApiDataFilter$fFromHttpApiDataFilter $fEqValuePath$fShowValuePath $fEqFilter $fShowFilter $fEqAttrPath$fShowAttrPath $fEqSubAttr $fShowSubAttr$fIsStringSubAttr $fEqCompareOp$fOrdCompareOp$fShowCompareOp$fEnumCompareOp$fBoundedCompareOp $fEqCompValue$fOrdCompValue$fShowCompValue ConfigSite ConfigurationdocumentationUripatchbulkfilterchangePasswordsortetagauthenticationSchemes FilterConfig maxResults BulkConfig maxOperationsmaxPayloadSize Supported supported subConfigempty configServer$fToJSONSupported$fToJSONBulkConfig$fToJSONFilterConfig$fToJSONConfiguration$fGenericConfigSite$fShowConfiguration$fEqConfiguration$fGenericConfiguration$fShowFilterConfig$fEqFilterConfig$fGenericFilterConfig$fShowBulkConfig$fEqBulkConfig$fGenericBulkConfig$fShowSupported $fEqSupported$fGenericSupportedAddress formatted streetAddresslocalityregion postalCodecountryprimary$fToJSONAddress$fFromJSONAddress $fShowAddress $fEqAddress$fGenericAddress Certificate$fToJSONCertificate$fFromJSONCertificate$fShowCertificate$fEqCertificate$fGenericCertificateEmail EmailAddress2unEmailAddress$fToJSONEmailAddress2$fFromJSONEmailAddress2 $fToJSONEmail$fFromJSONEmail $fShowEmail $fEqEmail$fGenericEmail$fShowEmailAddress2$fEqEmailAddress2IM $fToJSONIM $fFromJSONIM$fShowIM$fEqIM $fGenericIMName familyName givenName middleNamehonorificPrefixhonorificSuffix emptyName $fToJSONName$fFromJSONName $fShowName$fEqName $fGenericNamePhone $fToJSONPhone$fFromJSONPhone $fShowPhone $fEqPhone $fOrdPhone$fGenericPhonePhoto $fToJSONPhoto$fFromJSONPhoto $fShowPhoto $fEqPhoto$fGenericPhoto UserTypesUserId UserExtrasupportedSchemas PatchableapplyOperationPath NormalPath IntoValuePathOpAddReplaceRemove OperationoppathPatchOp getOperations parsePathpPathrPathoperationFromJSON pathFromJSON $fToJSONOp $fFromJSONOp $fToJSONPath$fToJSONOperation$fToJSONPatchOp$fFromJSONPatchOp$fPatchableHashMap $fEqPatchOp $fShowPatchOp $fEqOperation$fShowOperation$fEqPath $fShowPath$fEqOp$fShowOp$fEnumOp $fBoundedOp NoUserExtraUseruserName externalIdnickName profileUrltitleuserTypepreferredLanguagelocaleactivepasswordemails phoneNumbersimsphotos addresses entitlementsrolesx509Certificatesextra applyPatchresultToScimError isUserSchema$fPatchableUser $fToJSONUser$fFromJSONUser$fPatchableNoUserExtra$fToJSONNoUserExtra$fFromJSONNoUserExtra$fEqNoUserExtra$fShowNoUserExtra $fGenericUser$fEqUser $fShowUserUserDBgetUsersgetUserpostUserputUser patchUser deleteUserUserSite usGetUsers usGetUser usPostUser usPutUser usPatchUser usDeleteUser StoredUser userServer$fGenericUserSiteAppSiteAPIGroupAPIUserAPI ConfigAPI siteServermkappapp $fGenericSite TestServer TestStorageuserDBgroupDB GroupStorage UserStorageIdunIdMockemptyTestStorageliftSTMhoistSTMassertMutabilitytestDate createMetant filterUser$fAuthTypesMock$fGroupTypesMock$fUserTypesMock $fFromJSONId $fToJSONId$fAuthDBMockReaderT$fGroupDBMockReaderT$fUserDBMockReaderT$fEqId$fShowId$fOrdId $fHashableId$fToHttpApiDataId$fFromHttpApiDataIdTestTagFieldAcceptanceQueryConfigscimPathPrefix scimAuthTokenAcceptanceConfigscimAppAndConfig genUserNameresponsesFullyKnownshouldRespondWithshouldEventuallyRespondWithdefAcceptanceConfigdefAcceptanceQueryConfigpostputget'post'put'patch'delete'scimgetField$fFromValueValue$fFromValueByteString$fFromValueResponseMatcher $fToJSONField$fFromJSONField$fAuthTypesTestTag$fGroupTypesTestTag$fUserTypesTestTag $fEqField $fOrdField $fShowField $fReadField$fFunctorFieldignoremicrosoftAzure sampleUser1 getBinDir getLibDir getDynLibDir getDataDir getLibexecDir getSysconfDirgetDataFileNametransformers-0.5.6.2Control.Monad.Trans.ExceptExceptT mtl-2.2.2Control.Monad.Error.Class MonadError$aeson-1.4.7.1-BfXW20UbzkIIIL1zi6Ak8XData.Aeson.Types.InternalValuebase Data.EitherLeftGHC.BaseStringghc-prim GHC.TypesFalse&hspec-wai-0.9.2-2HqvjDN0gPxJ2F15hxaRChTest.Hspec.Wai.Internal WaiSessionTest.Hspec.Wairequest