From b1ce3be2ee2b746c0f96a26e6401a29a98668611 Mon Sep 17 00:00:00 2001 From: Matvey Aksenov Date: Sat, 4 Apr 2015 08:04:08 +0000 Subject: [PATCH] Update haddock documentation --- Ldap-Asn1-FromAsn1.html | 93 ++++++ Ldap-Asn1-ToAsn1.html | 116 +++++++ Ldap-Asn1-Type.html | 208 ++++++++++++ Ldap-Client-Add.html | 4 + Ldap-Client-Bind.html | 10 + Ldap-Client-Compare.html | 4 + Ldap-Client-Delete.html | 4 + Ldap-Client-Extended.html | 4 + Ldap-Client-Internal.html | 4 + Ldap-Client-Modify.html | 4 + Ldap-Client-Search.html | 4 + Ldap-Client.html | 4 + doc-index-58.html | 4 + doc-index-A.html | 4 + doc-index-All.html | 4 + doc-index-B.html | 4 + doc-index-C.html | 4 + doc-index-D.html | 4 + doc-index-E.html | 4 + doc-index-F.html | 4 + doc-index-G.html | 4 + doc-index-H.html | 4 + doc-index-I.html | 4 + doc-index-L.html | 4 + doc-index-M.html | 4 + doc-index-N.html | 4 + doc-index-O.html | 4 + doc-index-P.html | 4 + doc-index-R.html | 4 + doc-index-S.html | 4 + doc-index-T.html | 4 + doc-index-U.html | 4 + doc-index-W.html | 4 + doc-index.html | 4 + frames.html | 30 ++ haddock-util.js | 344 +++++++++++++++++++ hslogo-16.png | Bin 0 -> 1684 bytes index-frames.html | 4 + index.html | 4 + ldap-client.haddock | Bin 0 -> 56754 bytes mini_Ldap-Asn1-FromAsn1.html | 4 + mini_Ldap-Asn1-ToAsn1.html | 4 + mini_Ldap-Asn1-Type.html | 4 + mini_Ldap-Client-Add.html | 4 + mini_Ldap-Client-Bind.html | 4 + mini_Ldap-Client-Compare.html | 4 + mini_Ldap-Client-Delete.html | 4 + mini_Ldap-Client-Extended.html | 4 + mini_Ldap-Client-Internal.html | 4 + mini_Ldap-Client-Modify.html | 4 + mini_Ldap-Client-Search.html | 4 + mini_Ldap-Client.html | 4 + minus.gif | Bin 0 -> 56 bytes ocean.css | 587 +++++++++++++++++++++++++++++++++ plus.gif | Bin 0 -> 59 bytes src/Ldap-Asn1-FromAsn1.html | 389 ++++++++++++++++++++++ src/Ldap-Asn1-ToAsn1.html | 432 ++++++++++++++++++++++++ src/Ldap-Asn1-Type.html | 202 ++++++++++++ src/Ldap-Client-Add.html | 55 +++ src/Ldap-Client-Bind.html | 77 +++++ src/Ldap-Client-Compare.html | 57 ++++ src/Ldap-Client-Delete.html | 51 +++ src/Ldap-Client-Extended.html | 75 +++++ src/Ldap-Client-Internal.html | 123 +++++++ src/Ldap-Client-Modify.html | 102 ++++++ src/Ldap-Client-Search.html | 189 +++++++++++ src/Ldap-Client.html | 216 ++++++++++++ src/hscolour.css | 5 + synopsis.png | Bin 0 -> 11327 bytes 69 files changed, 3537 insertions(+) create mode 100644 Ldap-Asn1-FromAsn1.html create mode 100644 Ldap-Asn1-ToAsn1.html create mode 100644 Ldap-Asn1-Type.html create mode 100644 Ldap-Client-Add.html create mode 100644 Ldap-Client-Bind.html create mode 100644 Ldap-Client-Compare.html create mode 100644 Ldap-Client-Delete.html create mode 100644 Ldap-Client-Extended.html create mode 100644 Ldap-Client-Internal.html create mode 100644 Ldap-Client-Modify.html create mode 100644 Ldap-Client-Search.html create mode 100644 Ldap-Client.html create mode 100644 doc-index-58.html create mode 100644 doc-index-A.html create mode 100644 doc-index-All.html create mode 100644 doc-index-B.html create mode 100644 doc-index-C.html create mode 100644 doc-index-D.html create mode 100644 doc-index-E.html create mode 100644 doc-index-F.html create mode 100644 doc-index-G.html create mode 100644 doc-index-H.html create mode 100644 doc-index-I.html create mode 100644 doc-index-L.html create mode 100644 doc-index-M.html create mode 100644 doc-index-N.html create mode 100644 doc-index-O.html create mode 100644 doc-index-P.html create mode 100644 doc-index-R.html create mode 100644 doc-index-S.html create mode 100644 doc-index-T.html create mode 100644 doc-index-U.html create mode 100644 doc-index-W.html create mode 100644 doc-index.html create mode 100644 frames.html create mode 100644 haddock-util.js create mode 100644 hslogo-16.png create mode 100644 index-frames.html create mode 100644 index.html create mode 100644 ldap-client.haddock create mode 100644 mini_Ldap-Asn1-FromAsn1.html create mode 100644 mini_Ldap-Asn1-ToAsn1.html create mode 100644 mini_Ldap-Asn1-Type.html create mode 100644 mini_Ldap-Client-Add.html create mode 100644 mini_Ldap-Client-Bind.html create mode 100644 mini_Ldap-Client-Compare.html create mode 100644 mini_Ldap-Client-Delete.html create mode 100644 mini_Ldap-Client-Extended.html create mode 100644 mini_Ldap-Client-Internal.html create mode 100644 mini_Ldap-Client-Modify.html create mode 100644 mini_Ldap-Client-Search.html create mode 100644 mini_Ldap-Client.html create mode 100644 minus.gif create mode 100644 ocean.css create mode 100644 plus.gif create mode 100644 src/Ldap-Asn1-FromAsn1.html create mode 100644 src/Ldap-Asn1-ToAsn1.html create mode 100644 src/Ldap-Asn1-Type.html create mode 100644 src/Ldap-Client-Add.html create mode 100644 src/Ldap-Client-Bind.html create mode 100644 src/Ldap-Client-Compare.html create mode 100644 src/Ldap-Client-Delete.html create mode 100644 src/Ldap-Client-Extended.html create mode 100644 src/Ldap-Client-Internal.html create mode 100644 src/Ldap-Client-Modify.html create mode 100644 src/Ldap-Client-Search.html create mode 100644 src/Ldap-Client.html create mode 100644 src/hscolour.css create mode 100644 synopsis.png diff --git a/Ldap-Asn1-FromAsn1.html b/Ldap-Asn1-FromAsn1.html new file mode 100644 index 0000000..1375283 --- /dev/null +++ b/Ldap-Asn1-FromAsn1.html @@ -0,0 +1,93 @@ +Ldap.Asn1.FromAsn1

ldap-client-0.1.0: Pure Haskell LDAP Client Library

Safe HaskellNone
LanguageHaskell2010

Ldap.Asn1.FromAsn1

Documentation

class FromAsn1 a where Source

Methods

fromAsn1 :: Parser [ASN1] a Source

Instances

FromAsn1 LdapOid Source
LDAPOID ::= OCTET STRING -- Constrained to <numericoid>
+
FromAsn1 LdapString Source
LDAPString ::= OCTET STRING -- UTF-8 encoded,
+
FromAsn1 Uri Source
URI ::= LDAPString
+
FromAsn1 ReferralUris Source
Referral ::= SEQUENCE SIZE (1..MAX) OF uri URI
+
FromAsn1 LdapDn Source
LDAPDN ::= LDAPString
+
FromAsn1 PartialAttribute Source
PartialAttribute ::= SEQUENCE {
+     type       AttributeDescription,
+     vals       SET OF value AttributeValue }
+
FromAsn1 AttributeValue Source
AttributeValue ::= OCTET STRING
+
FromAsn1 AttributeDescription Source
AttributeDescription ::= LDAPString
+
FromAsn1 LdapResult Source
LDAPResult ::= SEQUENCE {
+     resultCode         ENUMERATED {
+          success                      (0),
+          operationsError              (1),
+          protocolError                (2),
+          timeLimitExceeded            (3),
+          sizeLimitExceeded            (4),
+          compareFalse                 (5),
+          compareTrue                  (6),
+          authMethodNotSupported       (7),
+          strongerAuthRequired         (8),
+          -- 9 reserved --
+          referral                     (10),
+          adminLimitExceeded           (11),
+          unavailableCriticalExtension (12),
+          confidentialityRequired      (13),
+          saslBindInProgress           (14),
+          noSuchAttribute              (16),
+          undefinedAttributeType       (17),
+          inappropriateMatching        (18),
+          constraintViolation          (19),
+          attributeOrValueExists       (20),
+          invalidAttributeSyntax       (21),
+          -- 22-31 unused --
+          noSuchObject                 (32),
+          aliasProblem                 (33),
+          invalidDNSyntax              (34),
+          -- 35 reserved for undefined isLeaf --
+          aliasDereferencingProblem    (36),
+          -- 37-47 unused --
+          inappropriateAuthentication  (48),
+          invalidCredentials           (49),
+          insufficientAccessRights     (50),
+          busy                         (51),
+          unavailable                  (52),
+          unwillingToPerform           (53),
+          loopDetect                   (54),
+          -- 55-63 unused --
+          namingViolation              (64),
+          objectClassViolation         (65),
+          notAllowedOnNonLeaf          (66),
+          notAllowedOnRDN              (67),
+          entryAlreadyExists           (68),
+          objectClassModsProhibited    (69),
+          -- 70 reserved for CLDAP --
+          affectsMultipleDSAs          (71),
+          -- 72-79 unused --
+          other                        (80),
+          ...  },
+     matchedDN          LDAPDN,
+     diagnosticMessage  LDAPString,
+     referral           [3] Referral OPTIONAL }
+
FromAsn1 PartialAttributeList Source
PartialAttributeList ::= SEQUENCE OF partialAttribute PartialAttribute
+
FromAsn1 ProtocolServerOp Source
BindResponse ::= [APPLICATION 1] SEQUENCE {
+     COMPONENTS OF LDAPResult,
+     serverSaslCreds    [7] OCTET STRING OPTIONAL }
+
SearchResultEntry ::= [APPLICATION 4] SEQUENCE {
+     objectName      LDAPDN,
+     attributes      PartialAttributeList }
+
SearchResultDone ::= [APPLICATION 5] LDAPResult
+
ModifyResponse ::= [APPLICATION 7] LDAPResult
+
AddResponse ::= [APPLICATION 9] LDAPResult
+
DelResponse ::= [APPLICATION 11] LDAPResult
+
CompareResponse ::= [APPLICATION 15] LDAPResult
+
FromAsn1 Id Source
MessageID ::= INTEGER (0 ..  maxInt)
+
FromAsn1 op => FromAsn1 (LdapMessage op) Source
LDAPMessage ::= SEQUENCE {
+     messageID       MessageID,
+     protocolOp      CHOICE {
+          bindRequest           BindRequest,
+          bindResponse          BindResponse,
+          unbindRequest         UnbindRequest,
+          searchRequest         SearchRequest,
+          searchResEntry        SearchResultEntry,
+          searchResDone         SearchResultDone,
+          searchResRef          SearchResultReference,
+          addRequest            AddRequest,
+          addResponse           AddResponse,
+          ... },
+     controls       [0] Controls OPTIONAL }
+
(FromAsn1 a, FromAsn1 b) => FromAsn1 (a, b) Source 

parseAsn1 :: FromAsn1 a => [ASN1] -> Maybe ([ASN1], a) Source

parse :: Parser s a -> s -> Maybe (s, a) Source

next :: Parser [s] s Source

\ No newline at end of file diff --git a/Ldap-Asn1-ToAsn1.html b/Ldap-Asn1-ToAsn1.html new file mode 100644 index 0000000..a5742e0 --- /dev/null +++ b/Ldap-Asn1-ToAsn1.html @@ -0,0 +1,116 @@ +Ldap.Asn1.ToAsn1

ldap-client-0.1.0: Pure Haskell LDAP Client Library

Safe HaskellNone
LanguageHaskell2010

Ldap.Asn1.ToAsn1

Documentation

class ToAsn1 a where Source

Methods

toAsn1 :: a -> Endo [ASN1] Source

Instances

ToAsn1 LdapOid Source
LDAPOID ::= OCTET STRING -- Constrained to <numericoid>
+
ToAsn1 LdapString Source
LDAPString ::= OCTET STRING -- UTF-8 encoded
+
ToAsn1 RelativeLdapDn Source
RelativeLDAPDN ::= LDAPString -- Constrained to <name-component>
+
ToAsn1 LdapDn Source
LDAPDN ::= LDAPString -- Constrained to <distinguishedName>
+
ToAsn1 PartialAttribute Source
PartialAttribute ::= SEQUENCE {
+     type       AttributeDescription,
+     vals       SET OF value AttributeValue }
+
ToAsn1 Attribute Source
Attribute ::= PartialAttribute(WITH COMPONENTS {
+     ...,
+     vals (SIZE(1..MAX))})
+
ToAsn1 AssertionValue Source
AssertionValue ::= OCTET STRING
+
ToAsn1 AttributeValueAssertion Source
AttributeValueAssertion ::= SEQUENCE {
+     attributeDesc   AttributeDescription,
+     assertionValue  AssertionValue }
+
ToAsn1 AttributeValue Source
AttributeValue ::= OCTET STRING
+
ToAsn1 AttributeDescription Source
AttributeDescription ::= LDAPString
+
ToAsn1 Control Source
Control ::= SEQUENCE {
+     controlType             LDAPOID,
+     criticality             BOOLEAN DEFAULT FALSE,
+     controlValue            OCTET STRING OPTIONAL }
+
ToAsn1 Controls Source
Controls ::= SEQUENCE OF control Control
+
ToAsn1 AttributeList Source
AttributeList ::= SEQUENCE OF attribute Attribute
+
ToAsn1 AttributeSelection Source
AttributeSelection ::= SEQUENCE OF selector LDAPString
+
ToAsn1 MatchingRuleId Source
MatchingRuleId ::= LDAPString
+
ToAsn1 MatchingRuleAssertion Source
MatchingRuleAssertion ::= SEQUENCE {
+     matchingRule    [1] MatchingRuleId OPTIONAL,
+     type            [2] AttributeDescription OPTIONAL,
+     matchValue      [3] AssertionValue,
+     dnAttributes    [4] BOOLEAN DEFAULT FALSE }
+
ToAsn1 SubstringFilter Source
SubstringFilter ::= SEQUENCE {
+     type           AttributeDescription,
+     substrings     SEQUENCE SIZE (1..MAX) OF substring CHOICE {
+          initial [0] AssertionValue,  -- can occur at most once
+          any     [1] AssertionValue,
+          final   [2] AssertionValue } -- can occur at most once
+     }
+
ToAsn1 Filter Source
Filter ::= CHOICE {
+     and             [0] SET SIZE (1..MAX) OF filter Filter,
+     or              [1] SET SIZE (1..MAX) OF filter Filter,
+     not             [2] Filter,
+     equalityMatch   [3] AttributeValueAssertion,
+     substrings      [4] SubstringFilter,
+     greaterOrEqual  [5] AttributeValueAssertion,
+     lessOrEqual     [6] AttributeValueAssertion,
+     present         [7] AttributeDescription,
+     approxMatch     [8] AttributeValueAssertion,
+     extensibleMatch [9] MatchingRuleAssertion,
+     ...  }
+
ToAsn1 AuthenticationChoice Source
AuthenticationChoice ::= CHOICE {
+     simple                  [0] OCTET STRING,
+     ...  }
+
ToAsn1 ProtocolClientOp Source
BindRequest ::= [APPLICATION 0] SEQUENCE {
+     version                 INTEGER (1 ..  127),
+     name                    LDAPDN,
+     authentication          AuthenticationChoice }
+
UnbindRequest ::= [APPLICATION 2] NULL
+
SearchRequest ::= [APPLICATION 3] SEQUENCE {
+     baseObject      LDAPDN,
+     scope           ENUMERATED {
+          baseObject              (0),
+          singleLevel             (1),
+          wholeSubtree            (2),
+          ...  },
+     derefAliases    ENUMERATED {
+          neverDerefAliases       (0),
+          derefInSearching        (1),
+          derefFindingBaseObj     (2),
+          derefAlways             (3) },
+     sizeLimit       INTEGER (0 ..  maxInt),
+     timeLimit       INTEGER (0 ..  maxInt),
+     typesOnly       BOOLEAN,
+     filter          Filter,
+     attributes      AttributeSelection }
+
ModifyRequest ::= [APPLICATION 6] SEQUENCE {
+     object          LDAPDN,
+     changes         SEQUENCE OF change SEQUENCE {
+          operation       ENUMERATED {
+               add     (0),
+               delete  (1),
+               replace (2),
+               ...  },
+          modification    PartialAttribute } }
+
AddRequest ::= [APPLICATION 8] SEQUENCE {
+     entry           LDAPDN,
+     attributes      AttributeList }
+
DelRequest ::= [APPLICATION 10] LDAPDN
+
ModifyDNRequest ::= [APPLICATION 12] SEQUENCE {
+     entry           LDAPDN,
+     newrdn          RelativeLDAPDN,
+     deleteoldrdn    BOOLEAN,
+     newSuperior     [0] LDAPDN OPTIONAL }
+
CompareRequest ::= [APPLICATION 14] SEQUENCE {
+     entry           LDAPDN,
+     ava             AttributeValueAssertion }
+
ExtendedRequest ::= [APPLICATION 23] SEQUENCE {
+     requestName      [0] LDAPOID,
+     requestValue     [1] OCTET STRING OPTIONAL }
+
ToAsn1 Id Source
MessageID ::= INTEGER (0 ..  maxInt)
+
ToAsn1 a => ToAsn1 [a] Source 
ToAsn1 a => ToAsn1 (NonEmpty a) Source 
ToAsn1 op => ToAsn1 (LdapMessage op) Source
LDAPMessage ::= SEQUENCE {
+     messageID       MessageID,
+     protocolOp      CHOICE {
+          bindRequest           BindRequest,
+          bindResponse          BindResponse,
+          unbindRequest         UnbindRequest,
+          searchRequest         SearchRequest,
+          searchResEntry        SearchResultEntry,
+          searchResDone         SearchResultDone,
+          searchResRef          SearchResultReference,
+          addRequest            AddRequest,
+          addResponse           AddResponse,
+          ... },
+     controls       [0] Controls OPTIONAL }
+
\ No newline at end of file diff --git a/Ldap-Asn1-Type.html b/Ldap-Asn1-Type.html new file mode 100644 index 0000000..00408d8 --- /dev/null +++ b/Ldap-Asn1-Type.html @@ -0,0 +1,208 @@ +Ldap.Asn1.Type

ldap-client-0.1.0: Pure Haskell LDAP Client Library

Safe HaskellSafe
LanguageHaskell2010

Ldap.Asn1.Type

Synopsis

Documentation

data LdapMessage op Source

Instances

Eq op => Eq (LdapMessage op) Source 
Ord op => Ord (LdapMessage op) Source 
Show op => Show (LdapMessage op) Source 
ToAsn1 op => ToAsn1 (LdapMessage op) Source
LDAPMessage ::= SEQUENCE {
+     messageID       MessageID,
+     protocolOp      CHOICE {
+          bindRequest           BindRequest,
+          bindResponse          BindResponse,
+          unbindRequest         UnbindRequest,
+          searchRequest         SearchRequest,
+          searchResEntry        SearchResultEntry,
+          searchResDone         SearchResultDone,
+          searchResRef          SearchResultReference,
+          addRequest            AddRequest,
+          addResponse           AddResponse,
+          ... },
+     controls       [0] Controls OPTIONAL }
+
FromAsn1 op => FromAsn1 (LdapMessage op) Source
LDAPMessage ::= SEQUENCE {
+     messageID       MessageID,
+     protocolOp      CHOICE {
+          bindRequest           BindRequest,
+          bindResponse          BindResponse,
+          unbindRequest         UnbindRequest,
+          searchRequest         SearchRequest,
+          searchResEntry        SearchResultEntry,
+          searchResDone         SearchResultDone,
+          searchResRef          SearchResultReference,
+          addRequest            AddRequest,
+          addResponse           AddResponse,
+          ... },
+     controls       [0] Controls OPTIONAL }
+

newtype Id Source

Constructors

Id 

Fields

unId :: Int32
 

Instances

Eq Id Source 
Ord Id Source 
Show Id Source 
ToAsn1 Id Source
MessageID ::= INTEGER (0 ..  maxInt)
+
FromAsn1 Id Source
MessageID ::= INTEGER (0 ..  maxInt)
+

data ProtocolClientOp Source

Instances

Eq ProtocolClientOp Source 
Ord ProtocolClientOp Source 
Show ProtocolClientOp Source 
ToAsn1 ProtocolClientOp Source
BindRequest ::= [APPLICATION 0] SEQUENCE {
+     version                 INTEGER (1 ..  127),
+     name                    LDAPDN,
+     authentication          AuthenticationChoice }
+
UnbindRequest ::= [APPLICATION 2] NULL
+
SearchRequest ::= [APPLICATION 3] SEQUENCE {
+     baseObject      LDAPDN,
+     scope           ENUMERATED {
+          baseObject              (0),
+          singleLevel             (1),
+          wholeSubtree            (2),
+          ...  },
+     derefAliases    ENUMERATED {
+          neverDerefAliases       (0),
+          derefInSearching        (1),
+          derefFindingBaseObj     (2),
+          derefAlways             (3) },
+     sizeLimit       INTEGER (0 ..  maxInt),
+     timeLimit       INTEGER (0 ..  maxInt),
+     typesOnly       BOOLEAN,
+     filter          Filter,
+     attributes      AttributeSelection }
+
ModifyRequest ::= [APPLICATION 6] SEQUENCE {
+     object          LDAPDN,
+     changes         SEQUENCE OF change SEQUENCE {
+          operation       ENUMERATED {
+               add     (0),
+               delete  (1),
+               replace (2),
+               ...  },
+          modification    PartialAttribute } }
+
AddRequest ::= [APPLICATION 8] SEQUENCE {
+     entry           LDAPDN,
+     attributes      AttributeList }
+
DelRequest ::= [APPLICATION 10] LDAPDN
+
ModifyDNRequest ::= [APPLICATION 12] SEQUENCE {
+     entry           LDAPDN,
+     newrdn          RelativeLDAPDN,
+     deleteoldrdn    BOOLEAN,
+     newSuperior     [0] LDAPDN OPTIONAL }
+
CompareRequest ::= [APPLICATION 14] SEQUENCE {
+     entry           LDAPDN,
+     ava             AttributeValueAssertion }
+
ExtendedRequest ::= [APPLICATION 23] SEQUENCE {
+     requestName      [0] LDAPOID,
+     requestValue     [1] OCTET STRING OPTIONAL }
+

data ProtocolServerOp Source

Instances

Eq ProtocolServerOp Source 
Ord ProtocolServerOp Source 
Show ProtocolServerOp Source 
FromAsn1 ProtocolServerOp Source
BindResponse ::= [APPLICATION 1] SEQUENCE {
+     COMPONENTS OF LDAPResult,
+     serverSaslCreds    [7] OCTET STRING OPTIONAL }
+
SearchResultEntry ::= [APPLICATION 4] SEQUENCE {
+     objectName      LDAPDN,
+     attributes      PartialAttributeList }
+
SearchResultDone ::= [APPLICATION 5] LDAPResult
+
ModifyResponse ::= [APPLICATION 7] LDAPResult
+
AddResponse ::= [APPLICATION 9] LDAPResult
+
DelResponse ::= [APPLICATION 11] LDAPResult
+
CompareResponse ::= [APPLICATION 15] LDAPResult
+

data AuthenticationChoice Source

Constructors

Simple ByteString 

Instances

Eq AuthenticationChoice Source 
Ord AuthenticationChoice Source 
Show AuthenticationChoice Source 
ToAsn1 AuthenticationChoice Source
AuthenticationChoice ::= CHOICE {
+     simple                  [0] OCTET STRING,
+     ...  }
+

data Filter Source

Instances

Eq Filter Source 
Ord Filter Source 
Show Filter Source 
ToAsn1 Filter Source
Filter ::= CHOICE {
+     and             [0] SET SIZE (1..MAX) OF filter Filter,
+     or              [1] SET SIZE (1..MAX) OF filter Filter,
+     not             [2] Filter,
+     equalityMatch   [3] AttributeValueAssertion,
+     substrings      [4] SubstringFilter,
+     greaterOrEqual  [5] AttributeValueAssertion,
+     lessOrEqual     [6] AttributeValueAssertion,
+     present         [7] AttributeDescription,
+     approxMatch     [8] AttributeValueAssertion,
+     extensibleMatch [9] MatchingRuleAssertion,
+     ...  }
+

data SubstringFilter Source

Instances

Eq SubstringFilter Source 
Ord SubstringFilter Source 
Show SubstringFilter Source 
ToAsn1 SubstringFilter Source
SubstringFilter ::= SEQUENCE {
+     type           AttributeDescription,
+     substrings     SEQUENCE SIZE (1..MAX) OF substring CHOICE {
+          initial [0] AssertionValue,  -- can occur at most once
+          any     [1] AssertionValue,
+          final   [2] AssertionValue } -- can occur at most once
+     }
+

data MatchingRuleAssertion Source

Instances

Eq MatchingRuleAssertion Source 
Ord MatchingRuleAssertion Source 
Show MatchingRuleAssertion Source 
ToAsn1 MatchingRuleAssertion Source
MatchingRuleAssertion ::= SEQUENCE {
+     matchingRule    [1] MatchingRuleId OPTIONAL,
+     type            [2] AttributeDescription OPTIONAL,
+     matchValue      [3] AssertionValue,
+     dnAttributes    [4] BOOLEAN DEFAULT FALSE }
+

newtype AttributeList Source

Constructors

AttributeList [Attribute] 

Instances

Eq AttributeList Source 
Ord AttributeList Source 
Show AttributeList Source 
ToAsn1 AttributeList Source
AttributeList ::= SEQUENCE OF attribute Attribute
+

newtype Controls Source

Constructors

Controls [Control] 

Instances

Eq Controls Source 
Ord Controls Source 
Show Controls Source 
ToAsn1 Controls Source
Controls ::= SEQUENCE OF control Control
+

data Control Source

Instances

Eq Control Source 
Ord Control Source 
Show Control Source 
ToAsn1 Control Source
Control ::= SEQUENCE {
+     controlType             LDAPOID,
+     criticality             BOOLEAN DEFAULT FALSE,
+     controlValue            OCTET STRING OPTIONAL }
+

data LdapResult Source

Instances

Eq LdapResult Source 
Ord LdapResult Source 
Show LdapResult Source 
FromAsn1 LdapResult Source
LDAPResult ::= SEQUENCE {
+     resultCode         ENUMERATED {
+          success                      (0),
+          operationsError              (1),
+          protocolError                (2),
+          timeLimitExceeded            (3),
+          sizeLimitExceeded            (4),
+          compareFalse                 (5),
+          compareTrue                  (6),
+          authMethodNotSupported       (7),
+          strongerAuthRequired         (8),
+          -- 9 reserved --
+          referral                     (10),
+          adminLimitExceeded           (11),
+          unavailableCriticalExtension (12),
+          confidentialityRequired      (13),
+          saslBindInProgress           (14),
+          noSuchAttribute              (16),
+          undefinedAttributeType       (17),
+          inappropriateMatching        (18),
+          constraintViolation          (19),
+          attributeOrValueExists       (20),
+          invalidAttributeSyntax       (21),
+          -- 22-31 unused --
+          noSuchObject                 (32),
+          aliasProblem                 (33),
+          invalidDNSyntax              (34),
+          -- 35 reserved for undefined isLeaf --
+          aliasDereferencingProblem    (36),
+          -- 37-47 unused --
+          inappropriateAuthentication  (48),
+          invalidCredentials           (49),
+          insufficientAccessRights     (50),
+          busy                         (51),
+          unavailable                  (52),
+          unwillingToPerform           (53),
+          loopDetect                   (54),
+          -- 55-63 unused --
+          namingViolation              (64),
+          objectClassViolation         (65),
+          notAllowedOnNonLeaf          (66),
+          notAllowedOnRDN              (67),
+          entryAlreadyExists           (68),
+          objectClassModsProhibited    (69),
+          -- 70 reserved for CLDAP --
+          affectsMultipleDSAs          (71),
+          -- 72-79 unused --
+          other                        (80),
+          ...  },
+     matchedDN          LDAPDN,
+     diagnosticMessage  LDAPString,
+     referral           [3] Referral OPTIONAL }
+

newtype AttributeValue Source

Instances

Eq AttributeValue Source 
Ord AttributeValue Source 
Show AttributeValue Source 
ToAsn1 AttributeValue Source
AttributeValue ::= OCTET STRING
+
FromAsn1 AttributeValue Source
AttributeValue ::= OCTET STRING
+

data AttributeValueAssertion Source

Instances

Eq AttributeValueAssertion Source 
Ord AttributeValueAssertion Source 
Show AttributeValueAssertion Source 
ToAsn1 AttributeValueAssertion Source
AttributeValueAssertion ::= SEQUENCE {
+     attributeDesc   AttributeDescription,
+     assertionValue  AssertionValue }
+

data Attribute Source

Instances

Eq Attribute Source 
Ord Attribute Source 
Show Attribute Source 
ToAsn1 Attribute Source
Attribute ::= PartialAttribute(WITH COMPONENTS {
+     ...,
+     vals (SIZE(1..MAX))})
+

data PartialAttribute Source

Instances

Eq PartialAttribute Source 
Ord PartialAttribute Source 
Show PartialAttribute Source 
ToAsn1 PartialAttribute Source
PartialAttribute ::= SEQUENCE {
+     type       AttributeDescription,
+     vals       SET OF value AttributeValue }
+
FromAsn1 PartialAttribute Source
PartialAttribute ::= SEQUENCE {
+     type       AttributeDescription,
+     vals       SET OF value AttributeValue }
+

newtype LdapDn Source

Constructors

LdapDn LdapString 

Instances

Eq LdapDn Source 
Ord LdapDn Source 
Show LdapDn Source 
ToAsn1 LdapDn Source
LDAPDN ::= LDAPString -- Constrained to <distinguishedName>
+
FromAsn1 LdapDn Source
LDAPDN ::= LDAPString
+

newtype RelativeLdapDn Source

Instances

Eq RelativeLdapDn Source 
Ord RelativeLdapDn Source 
Show RelativeLdapDn Source 
ToAsn1 RelativeLdapDn Source
RelativeLDAPDN ::= LDAPString -- Constrained to <name-component>
+

newtype ReferralUris Source

Constructors

ReferralUris (NonEmpty Uri) 

Instances

Eq ReferralUris Source 
Ord ReferralUris Source 
Show ReferralUris Source 
FromAsn1 ReferralUris Source
Referral ::= SEQUENCE SIZE (1..MAX) OF uri URI
+

newtype Uri Source

Constructors

Uri LdapString 

Instances

newtype LdapString Source

The LDAPString is a notational convenience to indicate that, although + strings of LDAPString type encode as ASN.1 OCTET STRING types, the + [ISO10646] character set (a superset of [Unicode]) is used, encoded + following the UTF-8 [RFC3629] algorithm.

Constructors

LdapString Text 

Instances

Eq LdapString Source 
Ord LdapString Source 
Show LdapString Source 
ToAsn1 LdapString Source
LDAPString ::= OCTET STRING -- UTF-8 encoded
+
FromAsn1 LdapString Source
LDAPString ::= OCTET STRING -- UTF-8 encoded,
+

newtype LdapOid Source

Constructors

LdapOid ByteString 

Instances

Eq LdapOid Source 
Ord LdapOid Source 
Show LdapOid Source 
ToAsn1 LdapOid Source
LDAPOID ::= OCTET STRING -- Constrained to <numericoid>
+
FromAsn1 LdapOid Source
LDAPOID ::= OCTET STRING -- Constrained to <numericoid>
+
\ No newline at end of file diff --git a/Ldap-Client-Add.html b/Ldap-Client-Add.html new file mode 100644 index 0000000..ad51456 --- /dev/null +++ b/Ldap-Client-Add.html @@ -0,0 +1,4 @@ +Ldap.Client.Add

ldap-client-0.1.0: Pure Haskell LDAP Client Library

Safe HaskellNone
LanguageHaskell2010

Ldap.Client.Add

\ No newline at end of file diff --git a/Ldap-Client-Bind.html b/Ldap-Client-Bind.html new file mode 100644 index 0000000..df16968 --- /dev/null +++ b/Ldap-Client-Bind.html @@ -0,0 +1,10 @@ +Ldap.Client.Bind

ldap-client-0.1.0: Pure Haskell LDAP Client Library

Safe HaskellNone
LanguageHaskell2010

Ldap.Client.Bind

Synopsis

Documentation

bind :: Ldap -> Dn -> Password -> IO () Source

unbindAsync :: Ldap -> IO () Source

Note that unbindAsync does not return an Async, + because LDAP server never responds to UnbindRequests, hence + a call to wait on a hypothetical Async would have resulted + in an exception anyway.

unbindAsyncSTM :: Ldap -> STM () Source

Note that unbindAsyncSTM does not return an Async, + because LDAP server never responds to UnbindRequests, hence + a call to wait on a hypothetical Async would have resulted + in an exception anyway.

\ No newline at end of file diff --git a/Ldap-Client-Compare.html b/Ldap-Client-Compare.html new file mode 100644 index 0000000..b20272c --- /dev/null +++ b/Ldap-Client-Compare.html @@ -0,0 +1,4 @@ +Ldap.Client.Compare

ldap-client-0.1.0: Pure Haskell LDAP Client Library

Safe HaskellNone
LanguageHaskell2010

Ldap.Client.Compare

\ No newline at end of file diff --git a/Ldap-Client-Delete.html b/Ldap-Client-Delete.html new file mode 100644 index 0000000..375d5b8 --- /dev/null +++ b/Ldap-Client-Delete.html @@ -0,0 +1,4 @@ +Ldap.Client.Delete

ldap-client-0.1.0: Pure Haskell LDAP Client Library

Safe HaskellNone
LanguageHaskell2010

Ldap.Client.Delete

Documentation

delete :: Ldap -> Dn -> IO () Source

\ No newline at end of file diff --git a/Ldap-Client-Extended.html b/Ldap-Client-Extended.html new file mode 100644 index 0000000..a44b004 --- /dev/null +++ b/Ldap-Client-Extended.html @@ -0,0 +1,4 @@ +Ldap.Client.Extended

ldap-client-0.1.0: Pure Haskell LDAP Client Library

Safe HaskellNone
LanguageHaskell2010

Ldap.Client.Extended

\ No newline at end of file diff --git a/Ldap-Client-Internal.html b/Ldap-Client-Internal.html new file mode 100644 index 0000000..7418adb --- /dev/null +++ b/Ldap-Client-Internal.html @@ -0,0 +1,4 @@ +Ldap.Client.Internal

ldap-client-0.1.0: Pure Haskell LDAP Client Library

Safe HaskellNone
LanguageHaskell2010

Ldap.Client.Internal

Synopsis

Documentation

data Ldap Source

Constructors

Ldap 

Fields

client :: TQueue ClientMessage
 

Instances

data Async a Source

Instances

newtype Oid Source

Constructors

Oid ByteString 

Instances

type AttrList f = [(Attr, f ByteString)] Source

Waiting for Request Completion

Misc

type Response = NonEmpty InMessage Source

raise :: Exception e => Either e a -> IO a Source

newtype Dn Source

Constructors

Dn Text 

Instances

newtype RelativeDn Source

Constructors

RelativeDn Text 

newtype Attr Source

Constructors

Attr Text 

unAttr :: Attr -> Text Source

\ No newline at end of file diff --git a/Ldap-Client-Modify.html b/Ldap-Client-Modify.html new file mode 100644 index 0000000..82abc30 --- /dev/null +++ b/Ldap-Client-Modify.html @@ -0,0 +1,4 @@ +Ldap.Client.Modify

ldap-client-0.1.0: Pure Haskell LDAP Client Library

Safe HaskellNone
LanguageHaskell2010

Ldap.Client.Modify

\ No newline at end of file diff --git a/Ldap-Client-Search.html b/Ldap-Client-Search.html new file mode 100644 index 0000000..8fd4ef9 --- /dev/null +++ b/Ldap-Client-Search.html @@ -0,0 +1,4 @@ +Ldap.Client.Search

ldap-client-0.1.0: Pure Haskell LDAP Client Library

Safe HaskellNone
LanguageHaskell2010

Ldap.Client.Search

\ No newline at end of file diff --git a/Ldap-Client.html b/Ldap-Client.html new file mode 100644 index 0000000..f7035dd --- /dev/null +++ b/Ldap-Client.html @@ -0,0 +1,4 @@ +Ldap.Client

ldap-client-0.1.0: Pure Haskell LDAP Client Library

Safe HaskellNone
LanguageHaskell2010

Ldap.Client

Synopsis

Documentation

data Ldap Source

Instances

data Async a Source

Instances

with :: Host -> PortNumber -> (Ldap -> IO a) -> IO (Either LdapError a) Source

The entrypoint into LDAP.

Bind

bind :: Ldap -> Dn -> Password -> IO () Source

Search

Search modifiers

data Mod a Source

Instances

Monoid (Mod a) Source 
Semigroup (Mod a) Source 

Modify

modify :: Ldap -> Dn -> [Operation] -> IO () Source

Add

Delete

delete :: Ldap -> Dn -> IO () Source

ModifyDn

modifyDn :: Ldap -> Dn -> RelativeDn -> Bool -> Maybe Dn -> IO () Source

Compare

Extended

Waiting for completion

Miscellanous

newtype Dn Source

Constructors

Dn Text 

Instances

newtype RelativeDn Source

Constructors

RelativeDn Text 

newtype Oid Source

Constructors

Oid ByteString 

Instances

type AttrList f = [(Attr, f ByteString)] Source

newtype Attr Source

Constructors

Attr Text 

Re-exports

data NonEmpty a :: * -> *

Instances

Monad NonEmpty 
Functor NonEmpty 
MonadFix NonEmpty 
Applicative NonEmpty 
Foldable NonEmpty 
Traversable NonEmpty 
Generic1 NonEmpty 
MonadZip NonEmpty 
IsList (NonEmpty a) 
Eq a => Eq (NonEmpty a) 
Data a => Data (NonEmpty a) 
Ord a => Ord (NonEmpty a) 
Read a => Read (NonEmpty a) 
Show a => Show (NonEmpty a) 
Generic (NonEmpty a) 
NFData a => NFData (NonEmpty a) 
Hashable a => Hashable (NonEmpty a) 
ToAsn1 a => ToAsn1 (NonEmpty a) 
Semigroup (NonEmpty a) 
type Rep1 NonEmpty = D1 D1NonEmpty (C1 C1_0NonEmpty ((:*:) (S1 NoSelector Par1) (S1 NoSelector (Rec1 [])))) 
type Rep (NonEmpty a) = D1 D1NonEmpty (C1 C1_0NonEmpty ((:*:) (S1 NoSelector (Rec0 a)) (S1 NoSelector (Rec0 [a])))) 
type Item (NonEmpty a) = a 
\ No newline at end of file diff --git a/doc-index-58.html b/doc-index-58.html new file mode 100644 index 0000000..eb8a855 --- /dev/null +++ b/doc-index-58.html @@ -0,0 +1,4 @@ +ldap-client-0.1.0: Pure Haskell LDAP Client Library (Index - :)

ldap-client-0.1.0: Pure Haskell LDAP Client Library

\ No newline at end of file diff --git a/doc-index-A.html b/doc-index-A.html new file mode 100644 index 0000000..83b816b --- /dev/null +++ b/doc-index-A.html @@ -0,0 +1,4 @@ +ldap-client-0.1.0: Pure Haskell LDAP Client Library (Index - A)

ldap-client-0.1.0: Pure Haskell LDAP Client Library

Index - A

Add 
1 (Data Constructor)Ldap.Asn1.Type
2 (Data Constructor)Ldap.Client.Modify, Ldap.Client
addLdap.Client.Add, Ldap.Client
addAsyncLdap.Client.Add
addAsyncSTMLdap.Client.Add
addEitherLdap.Client.Add
AddRequestLdap.Asn1.Type
AddResponseLdap.Asn1.Type
AdminLimitExceededLdap.Asn1.Type, Ldap.Client.Internal, Ldap.Client
AffectsMultipleDSAsLdap.Asn1.Type, Ldap.Client.Internal, Ldap.Client
AliasDereferencingProblemLdap.Asn1.Type, Ldap.Client.Internal, Ldap.Client
AliasProblemLdap.Asn1.Type, Ldap.Client.Internal, Ldap.Client
And 
1 (Data Constructor)Ldap.Asn1.Type
2 (Data Constructor)Ldap.Client.Search, Ldap.Client
AnyLdap.Asn1.Type
ApproxMatchLdap.Asn1.Type
AssertionValue 
1 (Type/Class)Ldap.Asn1.Type
2 (Data Constructor)Ldap.Asn1.Type
AsyncLdap.Client.Internal, Ldap.Client
Attr 
1 (Type/Class)Ldap.Client.Internal, Ldap.Client
2 (Data Constructor)Ldap.Client.Internal, Ldap.Client
Attribute 
1 (Type/Class)Ldap.Asn1.Type
2 (Data Constructor)Ldap.Asn1.Type
AttributeDescription 
1 (Type/Class)Ldap.Asn1.Type
2 (Data Constructor)Ldap.Asn1.Type
AttributeList 
1 (Type/Class)Ldap.Asn1.Type
2 (Data Constructor)Ldap.Asn1.Type
AttributeOrValueExistsLdap.Asn1.Type, Ldap.Client.Internal, Ldap.Client
AttributeSelection 
1 (Type/Class)Ldap.Asn1.Type
2 (Data Constructor)Ldap.Asn1.Type
AttributeValue 
1 (Type/Class)Ldap.Asn1.Type
2 (Data Constructor)Ldap.Asn1.Type
AttributeValueAssertion 
1 (Type/Class)Ldap.Asn1.Type
2 (Data Constructor)Ldap.Asn1.Type
AttrListLdap.Client.Internal, Ldap.Client
AuthenticationChoiceLdap.Asn1.Type
AuthMethodNotSupportedLdap.Asn1.Type, Ldap.Client.Internal, Ldap.Client
\ No newline at end of file diff --git a/doc-index-All.html b/doc-index-All.html new file mode 100644 index 0000000..200d2cc --- /dev/null +++ b/doc-index-All.html @@ -0,0 +1,4 @@ +ldap-client-0.1.0: Pure Haskell LDAP Client Library (Index)

ldap-client-0.1.0: Pure Haskell LDAP Client Library

Index

::=Ldap.Client.Search, Ldap.Client
:<=Ldap.Client.Search, Ldap.Client
:=Ldap.Client.Search, Ldap.Client
:=*Ldap.Client.Search, Ldap.Client
:>=Ldap.Client.Search, Ldap.Client
:~=Ldap.Client.Search, Ldap.Client
Add 
1 (Data Constructor)Ldap.Asn1.Type
2 (Data Constructor)Ldap.Client.Modify, Ldap.Client
addLdap.Client.Add, Ldap.Client
addAsyncLdap.Client.Add
addAsyncSTMLdap.Client.Add
addEitherLdap.Client.Add
AddRequestLdap.Asn1.Type
AddResponseLdap.Asn1.Type
AdminLimitExceededLdap.Asn1.Type, Ldap.Client.Internal, Ldap.Client
AffectsMultipleDSAsLdap.Asn1.Type, Ldap.Client.Internal, Ldap.Client
AliasDereferencingProblemLdap.Asn1.Type, Ldap.Client.Internal, Ldap.Client
AliasProblemLdap.Asn1.Type, Ldap.Client.Internal, Ldap.Client
And 
1 (Data Constructor)Ldap.Asn1.Type
2 (Data Constructor)Ldap.Client.Search, Ldap.Client
AnyLdap.Asn1.Type
ApproxMatchLdap.Asn1.Type
AssertionValue 
1 (Type/Class)Ldap.Asn1.Type
2 (Data Constructor)Ldap.Asn1.Type
AsyncLdap.Client.Internal, Ldap.Client
Attr 
1 (Type/Class)Ldap.Client.Internal, Ldap.Client
2 (Data Constructor)Ldap.Client.Internal, Ldap.Client
Attribute 
1 (Type/Class)Ldap.Asn1.Type
2 (Data Constructor)Ldap.Asn1.Type
AttributeDescription 
1 (Type/Class)Ldap.Asn1.Type
2 (Data Constructor)Ldap.Asn1.Type
AttributeList 
1 (Type/Class)Ldap.Asn1.Type
2 (Data Constructor)Ldap.Asn1.Type
AttributeOrValueExistsLdap.Asn1.Type, Ldap.Client.Internal, Ldap.Client
AttributeSelection 
1 (Type/Class)Ldap.Asn1.Type
2 (Data Constructor)Ldap.Asn1.Type
AttributeValue 
1 (Type/Class)Ldap.Asn1.Type
2 (Data Constructor)Ldap.Asn1.Type
AttributeValueAssertion 
1 (Type/Class)Ldap.Asn1.Type
2 (Data Constructor)Ldap.Asn1.Type
AttrListLdap.Client.Internal, Ldap.Client
AuthenticationChoiceLdap.Asn1.Type
AuthMethodNotSupportedLdap.Asn1.Type, Ldap.Client.Internal, Ldap.Client
BaseObjectLdap.Asn1.Type, Ldap.Client.Search, Ldap.Client
bindLdap.Client.Bind, Ldap.Client
bindAsyncLdap.Client.Bind
bindAsyncSTMLdap.Client.Bind
bindEitherLdap.Client.Bind
BindRequestLdap.Asn1.Type
BindResponseLdap.Asn1.Type
BusyLdap.Asn1.Type, Ldap.Client.Internal, Ldap.Client
clientLdap.Client.Internal
ClientMessageLdap.Client.Internal
compareLdap.Client.Compare, Ldap.Client
compareAsyncLdap.Client.Compare
compareAsyncSTMLdap.Client.Compare
compareEitherLdap.Client.Compare
CompareFalseLdap.Asn1.Type, Ldap.Client.Internal, Ldap.Client
CompareRequestLdap.Asn1.Type
CompareResponseLdap.Asn1.Type
CompareTrueLdap.Asn1.Type, Ldap.Client.Internal, Ldap.Client
ConfidentialityRequiredLdap.Asn1.Type, Ldap.Client.Internal, Ldap.Client
ConstraintViolationLdap.Asn1.Type, Ldap.Client.Internal, Ldap.Client
Control 
1 (Type/Class)Ldap.Asn1.Type
2 (Data Constructor)Ldap.Asn1.Type
Controls 
1 (Type/Class)Ldap.Asn1.Type
2 (Data Constructor)Ldap.Asn1.Type
Delete 
1 (Data Constructor)Ldap.Asn1.Type
2 (Data Constructor)Ldap.Client.Modify, Ldap.Client
deleteLdap.Client.Delete, Ldap.Client
deleteAsyncLdap.Client.Delete
deleteAsyncSTMLdap.Client.Delete
deleteEitherLdap.Client.Delete
DeleteRequestLdap.Asn1.Type
DeleteResponseLdap.Asn1.Type
DerefAliasesLdap.Asn1.Type
derefAliasesLdap.Client.Search, Ldap.Client
DerefAlwaysLdap.Asn1.Type
DerefFindingBaseObjectLdap.Asn1.Type
DerefInSearchingLdap.Asn1.Type
Dn 
1 (Type/Class)Ldap.Client.Internal, Ldap.Client
2 (Data Constructor)Ldap.Client.Internal, Ldap.Client
EntryAlreadyExistsLdap.Asn1.Type, Ldap.Client.Internal, Ldap.Client
EqualityMatchLdap.Asn1.Type
extendedLdap.Client.Extended, Ldap.Client
extendedAsyncLdap.Client.Extended
extendedAsyncSTMLdap.Client.Extended
extendedEitherLdap.Client.Extended
ExtendedRequestLdap.Asn1.Type
ExtendedResponseLdap.Asn1.Type
ExtensibleMatchLdap.Asn1.Type
Filter 
1 (Type/Class)Ldap.Asn1.Type
2 (Type/Class)Ldap.Client.Search, Ldap.Client
FinalLdap.Asn1.Type
FromAsn1Ldap.Asn1.FromAsn1
fromAsn1Ldap.Asn1.FromAsn1
GreaterOrEqualLdap.Asn1.Type
HostLdap.Client.Internal, Ldap.Client
Id 
1 (Type/Class)Ldap.Asn1.Type
2 (Data Constructor)Ldap.Asn1.Type
InappropriateAuthenticationLdap.Asn1.Type, Ldap.Client.Internal, Ldap.Client
InappropriateMatchingLdap.Asn1.Type, Ldap.Client.Internal, Ldap.Client
InitialLdap.Asn1.Type
InsecureLdap.Client.Internal, Ldap.Client
InsufficientAccessRightsLdap.Asn1.Type, Ldap.Client.Internal, Ldap.Client
InvalidAttributeSyntaxLdap.Asn1.Type, Ldap.Client.Internal, Ldap.Client
InvalidCredentialsLdap.Asn1.Type, Ldap.Client.Internal, Ldap.Client
InvalidDNSyntaxLdap.Asn1.Type, Ldap.Client.Internal, Ldap.Client
IOErrorLdap.Client
Ldap 
1 (Type/Class)Ldap.Client.Internal, Ldap.Client
2 (Data Constructor)Ldap.Client.Internal
LdapDn 
1 (Type/Class)Ldap.Asn1.Type
2 (Data Constructor)Ldap.Asn1.Type
LdapErrorLdap.Client
LdapMessage 
1 (Type/Class)Ldap.Asn1.Type
2 (Data Constructor)Ldap.Asn1.Type
ldapMessageControlsLdap.Asn1.Type
ldapMessageIdLdap.Asn1.Type
ldapMessageOpLdap.Asn1.Type
LdapOid 
1 (Type/Class)Ldap.Asn1.Type
2 (Data Constructor)Ldap.Asn1.Type
LdapResult 
1 (Type/Class)Ldap.Asn1.Type
2 (Data Constructor)Ldap.Asn1.Type
LdapString 
1 (Type/Class)Ldap.Asn1.Type
2 (Data Constructor)Ldap.Asn1.Type
LessOrEqualLdap.Asn1.Type
LoopDetectLdap.Asn1.Type, Ldap.Client.Internal, Ldap.Client
MatchingRuleAssertion 
1 (Type/Class)Ldap.Asn1.Type
2 (Data Constructor)Ldap.Asn1.Type
MatchingRuleId 
1 (Type/Class)Ldap.Asn1.Type
2 (Data Constructor)Ldap.Asn1.Type
ModLdap.Client.Search, Ldap.Client
modifyLdap.Client.Modify, Ldap.Client
modifyAsyncLdap.Client.Modify
modifyAsyncSTMLdap.Client.Modify
modifyDnLdap.Client.Modify, Ldap.Client
modifyDnAsyncLdap.Client.Modify
modifyDnAsyncSTMLdap.Client.Modify
modifyDnEitherLdap.Client.Modify
ModifyDnRequestLdap.Asn1.Type
ModifyDnResponseLdap.Asn1.Type
modifyEitherLdap.Client.Modify
ModifyRequestLdap.Asn1.Type
ModifyResponseLdap.Asn1.Type
NamingViolationLdap.Asn1.Type, Ldap.Client.Internal, Ldap.Client
NeverDerefAliasesLdap.Asn1.Type
NewLdap.Client.Internal
nextLdap.Asn1.FromAsn1
NonEmptyLdap.Client
NoSuchAttributeLdap.Asn1.Type, Ldap.Client.Internal, Ldap.Client
NoSuchObjectLdap.Asn1.Type, Ldap.Client.Internal, Ldap.Client
Not 
1 (Data Constructor)Ldap.Asn1.Type
2 (Data Constructor)Ldap.Client.Search, Ldap.Client
NotAllowedOnNonLeafLdap.Asn1.Type, Ldap.Client.Internal, Ldap.Client
NotAllowedOnRDNLdap.Asn1.Type, Ldap.Client.Internal, Ldap.Client
ObjectClassModsProhibitedLdap.Asn1.Type, Ldap.Client.Internal, Ldap.Client
ObjectClassViolationLdap.Asn1.Type, Ldap.Client.Internal, Ldap.Client
Oid 
1 (Type/Class)Ldap.Client.Internal, Ldap.Client
2 (Data Constructor)Ldap.Client.Internal, Ldap.Client
Operation 
1 (Type/Class)Ldap.Asn1.Type
2 (Type/Class)Ldap.Client.Modify, Ldap.Client
OperationErrorLdap.Asn1.Type, Ldap.Client.Internal, Ldap.Client
Or 
1 (Data Constructor)Ldap.Asn1.Type
2 (Data Constructor)Ldap.Client.Search, Ldap.Client
OtherLdap.Asn1.Type, Ldap.Client.Internal, Ldap.Client
parseLdap.Asn1.FromAsn1
parseAsn1Ldap.Asn1.FromAsn1
ParseErrorLdap.Client
ParserLdap.Asn1.FromAsn1
PartialAttribute 
1 (Type/Class)Ldap.Asn1.Type
2 (Data Constructor)Ldap.Asn1.Type
PartialAttributeList 
1 (Type/Class)Ldap.Asn1.Type
2 (Data Constructor)Ldap.Asn1.Type
Password 
1 (Type/Class)Ldap.Client.Internal, Ldap.Client
2 (Data Constructor)Ldap.Client.Internal, Ldap.Client
PlainLdap.Client.Internal, Ldap.Client
PortNumberLdap.Client.Internal, Ldap.Client
Present 
1 (Data Constructor)Ldap.Asn1.Type
2 (Data Constructor)Ldap.Client.Search, Ldap.Client
ProtocolClientOpLdap.Asn1.Type
ProtocolErrorLdap.Asn1.Type, Ldap.Client.Internal, Ldap.Client
ProtocolServerOpLdap.Asn1.Type
raiseLdap.Client.Internal
ReferralLdap.Asn1.Type, Ldap.Client.Internal, Ldap.Client
ReferralUris 
1 (Type/Class)Ldap.Asn1.Type
2 (Data Constructor)Ldap.Asn1.Type
RelativeDn 
1 (Type/Class)Ldap.Client.Internal, Ldap.Client
2 (Data Constructor)Ldap.Client.Internal, Ldap.Client
RelativeLdapDn 
1 (Type/Class)Ldap.Asn1.Type
2 (Data Constructor)Ldap.Asn1.Type
Replace 
1 (Data Constructor)Ldap.Asn1.Type
2 (Data Constructor)Ldap.Client.Modify, Ldap.Client
RequestLdap.Client.Internal
ResponseLdap.Client.Internal
ResponseError 
1 (Type/Class)Ldap.Client.Internal, Ldap.Client
2 (Data Constructor)Ldap.Client
ResponseErrorCodeLdap.Client.Internal, Ldap.Client
ResponseInvalidLdap.Client.Internal, Ldap.Client
ResultCodeLdap.Asn1.Type, Ldap.Client.Internal, Ldap.Client
SaslBindInProgressLdap.Asn1.Type, Ldap.Client.Internal, Ldap.Client
ScopeLdap.Asn1.Type, Ldap.Client.Search, Ldap.Client
scopeLdap.Client.Search, Ldap.Client
SearchLdap.Client.Search, Ldap.Client
searchLdap.Client.Search, Ldap.Client
searchAsyncLdap.Client.Search
searchAsyncSTMLdap.Client.Search
searchEitherLdap.Client.Search
SearchEntry 
1 (Type/Class)Ldap.Client.Search, Ldap.Client
2 (Data Constructor)Ldap.Client.Search, Ldap.Client
SearchRequestLdap.Asn1.Type
SearchResultDoneLdap.Asn1.Type
SearchResultEntryLdap.Asn1.Type
SearchResultReferenceLdap.Asn1.Type
SecureLdap.Client.Internal, Ldap.Client
sendRequestLdap.Client.Internal
SimpleLdap.Asn1.Type
SingleLevelLdap.Asn1.Type, Ldap.Client.Search, Ldap.Client
sizeLdap.Client.Search, Ldap.Client
SizeLimitExceededLdap.Asn1.Type, Ldap.Client.Internal, Ldap.Client
startTlsLdap.Client.Extended
startTlsAsyncLdap.Client.Extended
startTlsAsyncSTMLdap.Client.Extended
startTlsEitherLdap.Client.Extended
StrongerAuthRequiredLdap.Asn1.Type, Ldap.Client.Internal, Ldap.Client
SubstringLdap.Asn1.Type
SubstringFilter 
1 (Type/Class)Ldap.Asn1.Type
2 (Data Constructor)Ldap.Asn1.Type
SubstringsLdap.Asn1.Type
SuccessLdap.Asn1.Type, Ldap.Client.Internal, Ldap.Client
timeLdap.Client.Search, Ldap.Client
TimeLimitExceededLdap.Asn1.Type, Ldap.Client.Internal, Ldap.Client
ToAsn1Ldap.Asn1.ToAsn1
toAsn1Ldap.Asn1.ToAsn1
typesOnlyLdap.Client.Search, Ldap.Client
unAttrLdap.Client.Internal
UnavailableLdap.Asn1.Type, Ldap.Client.Internal, Ldap.Client
UnavailableCriticalExtensionLdap.Asn1.Type, Ldap.Client.Internal, Ldap.Client
unbindAsyncLdap.Client.Bind
unbindAsyncSTMLdap.Client.Bind
UnbindRequestLdap.Asn1.Type
UndefinedAttributeTypeLdap.Asn1.Type, Ldap.Client.Internal, Ldap.Client
unIdLdap.Asn1.Type
UnwillingToPerformLdap.Asn1.Type, Ldap.Client.Internal, Ldap.Client
Uri 
1 (Type/Class)Ldap.Asn1.Type
2 (Data Constructor)Ldap.Asn1.Type
waitLdap.Client.Internal, Ldap.Client
waitSTMLdap.Client.Internal
WholeSubtreeLdap.Asn1.Type, Ldap.Client.Search, Ldap.Client
withLdap.Client
\ No newline at end of file diff --git a/doc-index-B.html b/doc-index-B.html new file mode 100644 index 0000000..e0f2bac --- /dev/null +++ b/doc-index-B.html @@ -0,0 +1,4 @@ +ldap-client-0.1.0: Pure Haskell LDAP Client Library (Index - B)

ldap-client-0.1.0: Pure Haskell LDAP Client Library

\ No newline at end of file diff --git a/doc-index-C.html b/doc-index-C.html new file mode 100644 index 0000000..2130975 --- /dev/null +++ b/doc-index-C.html @@ -0,0 +1,4 @@ +ldap-client-0.1.0: Pure Haskell LDAP Client Library (Index - C)

ldap-client-0.1.0: Pure Haskell LDAP Client Library

Index - C

clientLdap.Client.Internal
ClientMessageLdap.Client.Internal
compareLdap.Client.Compare, Ldap.Client
compareAsyncLdap.Client.Compare
compareAsyncSTMLdap.Client.Compare
compareEitherLdap.Client.Compare
CompareFalseLdap.Asn1.Type, Ldap.Client.Internal, Ldap.Client
CompareRequestLdap.Asn1.Type
CompareResponseLdap.Asn1.Type
CompareTrueLdap.Asn1.Type, Ldap.Client.Internal, Ldap.Client
ConfidentialityRequiredLdap.Asn1.Type, Ldap.Client.Internal, Ldap.Client
ConstraintViolationLdap.Asn1.Type, Ldap.Client.Internal, Ldap.Client
Control 
1 (Type/Class)Ldap.Asn1.Type
2 (Data Constructor)Ldap.Asn1.Type
Controls 
1 (Type/Class)Ldap.Asn1.Type
2 (Data Constructor)Ldap.Asn1.Type
\ No newline at end of file diff --git a/doc-index-D.html b/doc-index-D.html new file mode 100644 index 0000000..47b33ad --- /dev/null +++ b/doc-index-D.html @@ -0,0 +1,4 @@ +ldap-client-0.1.0: Pure Haskell LDAP Client Library (Index - D)

ldap-client-0.1.0: Pure Haskell LDAP Client Library

Index - D

Delete 
1 (Data Constructor)Ldap.Asn1.Type
2 (Data Constructor)Ldap.Client.Modify, Ldap.Client
deleteLdap.Client.Delete, Ldap.Client
deleteAsyncLdap.Client.Delete
deleteAsyncSTMLdap.Client.Delete
deleteEitherLdap.Client.Delete
DeleteRequestLdap.Asn1.Type
DeleteResponseLdap.Asn1.Type
DerefAliasesLdap.Asn1.Type
derefAliasesLdap.Client.Search, Ldap.Client
DerefAlwaysLdap.Asn1.Type
DerefFindingBaseObjectLdap.Asn1.Type
DerefInSearchingLdap.Asn1.Type
Dn 
1 (Type/Class)Ldap.Client.Internal, Ldap.Client
2 (Data Constructor)Ldap.Client.Internal, Ldap.Client
\ No newline at end of file diff --git a/doc-index-E.html b/doc-index-E.html new file mode 100644 index 0000000..e86ffd9 --- /dev/null +++ b/doc-index-E.html @@ -0,0 +1,4 @@ +ldap-client-0.1.0: Pure Haskell LDAP Client Library (Index - E)

ldap-client-0.1.0: Pure Haskell LDAP Client Library

Index - E

EntryAlreadyExistsLdap.Asn1.Type, Ldap.Client.Internal, Ldap.Client
EqualityMatchLdap.Asn1.Type
extendedLdap.Client.Extended, Ldap.Client
extendedAsyncLdap.Client.Extended
extendedAsyncSTMLdap.Client.Extended
extendedEitherLdap.Client.Extended
ExtendedRequestLdap.Asn1.Type
ExtendedResponseLdap.Asn1.Type
ExtensibleMatchLdap.Asn1.Type
\ No newline at end of file diff --git a/doc-index-F.html b/doc-index-F.html new file mode 100644 index 0000000..c2364f2 --- /dev/null +++ b/doc-index-F.html @@ -0,0 +1,4 @@ +ldap-client-0.1.0: Pure Haskell LDAP Client Library (Index - F)

ldap-client-0.1.0: Pure Haskell LDAP Client Library

Index - F

Filter 
1 (Type/Class)Ldap.Asn1.Type
2 (Type/Class)Ldap.Client.Search, Ldap.Client
FinalLdap.Asn1.Type
FromAsn1Ldap.Asn1.FromAsn1
fromAsn1Ldap.Asn1.FromAsn1
\ No newline at end of file diff --git a/doc-index-G.html b/doc-index-G.html new file mode 100644 index 0000000..4cd5007 --- /dev/null +++ b/doc-index-G.html @@ -0,0 +1,4 @@ +ldap-client-0.1.0: Pure Haskell LDAP Client Library (Index - G)

ldap-client-0.1.0: Pure Haskell LDAP Client Library

Index - G

GreaterOrEqualLdap.Asn1.Type
\ No newline at end of file diff --git a/doc-index-H.html b/doc-index-H.html new file mode 100644 index 0000000..1fe8663 --- /dev/null +++ b/doc-index-H.html @@ -0,0 +1,4 @@ +ldap-client-0.1.0: Pure Haskell LDAP Client Library (Index - H)

ldap-client-0.1.0: Pure Haskell LDAP Client Library

\ No newline at end of file diff --git a/doc-index-I.html b/doc-index-I.html new file mode 100644 index 0000000..4ca0f6e --- /dev/null +++ b/doc-index-I.html @@ -0,0 +1,4 @@ +ldap-client-0.1.0: Pure Haskell LDAP Client Library (Index - I)

ldap-client-0.1.0: Pure Haskell LDAP Client Library

\ No newline at end of file diff --git a/doc-index-L.html b/doc-index-L.html new file mode 100644 index 0000000..2731ae8 --- /dev/null +++ b/doc-index-L.html @@ -0,0 +1,4 @@ +ldap-client-0.1.0: Pure Haskell LDAP Client Library (Index - L)

ldap-client-0.1.0: Pure Haskell LDAP Client Library

Index - L

Ldap 
1 (Type/Class)Ldap.Client.Internal, Ldap.Client
2 (Data Constructor)Ldap.Client.Internal
LdapDn 
1 (Type/Class)Ldap.Asn1.Type
2 (Data Constructor)Ldap.Asn1.Type
LdapErrorLdap.Client
LdapMessage 
1 (Type/Class)Ldap.Asn1.Type
2 (Data Constructor)Ldap.Asn1.Type
ldapMessageControlsLdap.Asn1.Type
ldapMessageIdLdap.Asn1.Type
ldapMessageOpLdap.Asn1.Type
LdapOid 
1 (Type/Class)Ldap.Asn1.Type
2 (Data Constructor)Ldap.Asn1.Type
LdapResult 
1 (Type/Class)Ldap.Asn1.Type
2 (Data Constructor)Ldap.Asn1.Type
LdapString 
1 (Type/Class)Ldap.Asn1.Type
2 (Data Constructor)Ldap.Asn1.Type
LessOrEqualLdap.Asn1.Type
LoopDetectLdap.Asn1.Type, Ldap.Client.Internal, Ldap.Client
\ No newline at end of file diff --git a/doc-index-M.html b/doc-index-M.html new file mode 100644 index 0000000..14377b0 --- /dev/null +++ b/doc-index-M.html @@ -0,0 +1,4 @@ +ldap-client-0.1.0: Pure Haskell LDAP Client Library (Index - M)

ldap-client-0.1.0: Pure Haskell LDAP Client Library

Index - M

MatchingRuleAssertion 
1 (Type/Class)Ldap.Asn1.Type
2 (Data Constructor)Ldap.Asn1.Type
MatchingRuleId 
1 (Type/Class)Ldap.Asn1.Type
2 (Data Constructor)Ldap.Asn1.Type
ModLdap.Client.Search, Ldap.Client
modifyLdap.Client.Modify, Ldap.Client
modifyAsyncLdap.Client.Modify
modifyAsyncSTMLdap.Client.Modify
modifyDnLdap.Client.Modify, Ldap.Client
modifyDnAsyncLdap.Client.Modify
modifyDnAsyncSTMLdap.Client.Modify
modifyDnEitherLdap.Client.Modify
ModifyDnRequestLdap.Asn1.Type
ModifyDnResponseLdap.Asn1.Type
modifyEitherLdap.Client.Modify
ModifyRequestLdap.Asn1.Type
ModifyResponseLdap.Asn1.Type
\ No newline at end of file diff --git a/doc-index-N.html b/doc-index-N.html new file mode 100644 index 0000000..95f5559 --- /dev/null +++ b/doc-index-N.html @@ -0,0 +1,4 @@ +ldap-client-0.1.0: Pure Haskell LDAP Client Library (Index - N)

ldap-client-0.1.0: Pure Haskell LDAP Client Library

\ No newline at end of file diff --git a/doc-index-O.html b/doc-index-O.html new file mode 100644 index 0000000..1ee8e79 --- /dev/null +++ b/doc-index-O.html @@ -0,0 +1,4 @@ +ldap-client-0.1.0: Pure Haskell LDAP Client Library (Index - O)

ldap-client-0.1.0: Pure Haskell LDAP Client Library

Index - O

ObjectClassModsProhibitedLdap.Asn1.Type, Ldap.Client.Internal, Ldap.Client
ObjectClassViolationLdap.Asn1.Type, Ldap.Client.Internal, Ldap.Client
Oid 
1 (Type/Class)Ldap.Client.Internal, Ldap.Client
2 (Data Constructor)Ldap.Client.Internal, Ldap.Client
Operation 
1 (Type/Class)Ldap.Asn1.Type
2 (Type/Class)Ldap.Client.Modify, Ldap.Client
OperationErrorLdap.Asn1.Type, Ldap.Client.Internal, Ldap.Client
Or 
1 (Data Constructor)Ldap.Asn1.Type
2 (Data Constructor)Ldap.Client.Search, Ldap.Client
OtherLdap.Asn1.Type, Ldap.Client.Internal, Ldap.Client
\ No newline at end of file diff --git a/doc-index-P.html b/doc-index-P.html new file mode 100644 index 0000000..09bd77b --- /dev/null +++ b/doc-index-P.html @@ -0,0 +1,4 @@ +ldap-client-0.1.0: Pure Haskell LDAP Client Library (Index - P)

ldap-client-0.1.0: Pure Haskell LDAP Client Library

Index - P

parseLdap.Asn1.FromAsn1
parseAsn1Ldap.Asn1.FromAsn1
ParseErrorLdap.Client
ParserLdap.Asn1.FromAsn1
PartialAttribute 
1 (Type/Class)Ldap.Asn1.Type
2 (Data Constructor)Ldap.Asn1.Type
PartialAttributeList 
1 (Type/Class)Ldap.Asn1.Type
2 (Data Constructor)Ldap.Asn1.Type
Password 
1 (Type/Class)Ldap.Client.Internal, Ldap.Client
2 (Data Constructor)Ldap.Client.Internal, Ldap.Client
PlainLdap.Client.Internal, Ldap.Client
PortNumberLdap.Client.Internal, Ldap.Client
Present 
1 (Data Constructor)Ldap.Asn1.Type
2 (Data Constructor)Ldap.Client.Search, Ldap.Client
ProtocolClientOpLdap.Asn1.Type
ProtocolErrorLdap.Asn1.Type, Ldap.Client.Internal, Ldap.Client
ProtocolServerOpLdap.Asn1.Type
\ No newline at end of file diff --git a/doc-index-R.html b/doc-index-R.html new file mode 100644 index 0000000..80f5829 --- /dev/null +++ b/doc-index-R.html @@ -0,0 +1,4 @@ +ldap-client-0.1.0: Pure Haskell LDAP Client Library (Index - R)

ldap-client-0.1.0: Pure Haskell LDAP Client Library

Index - R

raiseLdap.Client.Internal
ReferralLdap.Asn1.Type, Ldap.Client.Internal, Ldap.Client
ReferralUris 
1 (Type/Class)Ldap.Asn1.Type
2 (Data Constructor)Ldap.Asn1.Type
RelativeDn 
1 (Type/Class)Ldap.Client.Internal, Ldap.Client
2 (Data Constructor)Ldap.Client.Internal, Ldap.Client
RelativeLdapDn 
1 (Type/Class)Ldap.Asn1.Type
2 (Data Constructor)Ldap.Asn1.Type
Replace 
1 (Data Constructor)Ldap.Asn1.Type
2 (Data Constructor)Ldap.Client.Modify, Ldap.Client
RequestLdap.Client.Internal
ResponseLdap.Client.Internal
ResponseError 
1 (Type/Class)Ldap.Client.Internal, Ldap.Client
2 (Data Constructor)Ldap.Client
ResponseErrorCodeLdap.Client.Internal, Ldap.Client
ResponseInvalidLdap.Client.Internal, Ldap.Client
ResultCodeLdap.Asn1.Type, Ldap.Client.Internal, Ldap.Client
\ No newline at end of file diff --git a/doc-index-S.html b/doc-index-S.html new file mode 100644 index 0000000..603b37f --- /dev/null +++ b/doc-index-S.html @@ -0,0 +1,4 @@ +ldap-client-0.1.0: Pure Haskell LDAP Client Library (Index - S)

ldap-client-0.1.0: Pure Haskell LDAP Client Library

\ No newline at end of file diff --git a/doc-index-T.html b/doc-index-T.html new file mode 100644 index 0000000..2c86a6f --- /dev/null +++ b/doc-index-T.html @@ -0,0 +1,4 @@ +ldap-client-0.1.0: Pure Haskell LDAP Client Library (Index - T)

ldap-client-0.1.0: Pure Haskell LDAP Client Library

\ No newline at end of file diff --git a/doc-index-U.html b/doc-index-U.html new file mode 100644 index 0000000..0961a58 --- /dev/null +++ b/doc-index-U.html @@ -0,0 +1,4 @@ +ldap-client-0.1.0: Pure Haskell LDAP Client Library (Index - U)

ldap-client-0.1.0: Pure Haskell LDAP Client Library

\ No newline at end of file diff --git a/doc-index-W.html b/doc-index-W.html new file mode 100644 index 0000000..686aea4 --- /dev/null +++ b/doc-index-W.html @@ -0,0 +1,4 @@ +ldap-client-0.1.0: Pure Haskell LDAP Client Library (Index - W)

ldap-client-0.1.0: Pure Haskell LDAP Client Library

\ No newline at end of file diff --git a/doc-index.html b/doc-index.html new file mode 100644 index 0000000..48a73ea --- /dev/null +++ b/doc-index.html @@ -0,0 +1,4 @@ +ldap-client-0.1.0: Pure Haskell LDAP Client Library (Index)

ldap-client-0.1.0: Pure Haskell LDAP Client Library

\ No newline at end of file diff --git a/frames.html b/frames.html new file mode 100644 index 0000000..1b4e38d --- /dev/null +++ b/frames.html @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + diff --git a/haddock-util.js b/haddock-util.js new file mode 100644 index 0000000..9a6fccf --- /dev/null +++ b/haddock-util.js @@ -0,0 +1,344 @@ +// Haddock JavaScript utilities + +var rspace = /\s\s+/g, + rtrim = /^\s+|\s+$/g; + +function spaced(s) { return (" " + s + " ").replace(rspace, " "); } +function trim(s) { return s.replace(rtrim, ""); } + +function hasClass(elem, value) { + var className = spaced(elem.className || ""); + return className.indexOf( " " + value + " " ) >= 0; +} + +function addClass(elem, value) { + var className = spaced(elem.className || ""); + if ( className.indexOf( " " + value + " " ) < 0 ) { + elem.className = trim(className + " " + value); + } +} + +function removeClass(elem, value) { + var className = spaced(elem.className || ""); + className = className.replace(" " + value + " ", " "); + elem.className = trim(className); +} + +function toggleClass(elem, valueOn, valueOff, bool) { + if (bool == null) { bool = ! hasClass(elem, valueOn); } + if (bool) { + removeClass(elem, valueOff); + addClass(elem, valueOn); + } + else { + removeClass(elem, valueOn); + addClass(elem, valueOff); + } + return bool; +} + + +function makeClassToggle(valueOn, valueOff) +{ + return function(elem, bool) { + return toggleClass(elem, valueOn, valueOff, bool); + } +} + +toggleShow = makeClassToggle("show", "hide"); +toggleCollapser = makeClassToggle("collapser", "expander"); + +function toggleSection(id) +{ + var b = toggleShow(document.getElementById("section." + id)); + toggleCollapser(document.getElementById("control." + id), b); + rememberCollapsed(id, b); + return b; +} + +var collapsed = {}; +function rememberCollapsed(id, b) +{ + if(b) + delete collapsed[id] + else + collapsed[id] = null; + + var sections = []; + for(var i in collapsed) + { + if(collapsed.hasOwnProperty(i)) + sections.push(i); + } + // cookie specific to this page; don't use setCookie which sets path=/ + document.cookie = "collapsed=" + escape(sections.join('+')); +} + +function restoreCollapsed() +{ + var cookie = getCookie("collapsed"); + if(!cookie) + return; + + var ids = cookie.split('+'); + for(var i in ids) + { + if(document.getElementById("section." + ids[i])) + toggleSection(ids[i]); + } +} + +function setCookie(name, value) { + document.cookie = name + "=" + escape(value) + ";path=/;"; +} + +function clearCookie(name) { + document.cookie = name + "=;path=/;expires=Thu, 01-Jan-1970 00:00:01 GMT;"; +} + +function getCookie(name) { + var nameEQ = name + "="; + var ca = document.cookie.split(';'); + for(var i=0;i < ca.length;i++) { + var c = ca[i]; + while (c.charAt(0)==' ') c = c.substring(1,c.length); + if (c.indexOf(nameEQ) == 0) { + return unescape(c.substring(nameEQ.length,c.length)); + } + } + return null; +} + + + +var max_results = 75; // 50 is not enough to search for map in the base libraries +var shown_range = null; +var last_search = null; + +function quick_search() +{ + perform_search(false); +} + +function full_search() +{ + perform_search(true); +} + + +function perform_search(full) +{ + var text = document.getElementById("searchbox").value.toLowerCase(); + if (text == last_search && !full) return; + last_search = text; + + var table = document.getElementById("indexlist"); + var status = document.getElementById("searchmsg"); + var children = table.firstChild.childNodes; + + // first figure out the first node with the prefix + var first = bisect(-1); + var last = (first == -1 ? -1 : bisect(1)); + + if (first == -1) + { + table.className = ""; + status.innerHTML = "No results found, displaying all"; + } + else if (first == 0 && last == children.length - 1) + { + table.className = ""; + status.innerHTML = ""; + } + else if (last - first >= max_results && !full) + { + table.className = ""; + status.innerHTML = "More than " + max_results + ", press Search to display"; + } + else + { + // decide what you need to clear/show + if (shown_range) + setclass(shown_range[0], shown_range[1], "indexrow"); + setclass(first, last, "indexshow"); + shown_range = [first, last]; + table.className = "indexsearch"; + status.innerHTML = ""; + } + + + function setclass(first, last, status) + { + for (var i = first; i <= last; i++) + { + children[i].className = status; + } + } + + + // do a binary search, treating 0 as ... + // return either -1 (no 0's found) or location of most far match + function bisect(dir) + { + var first = 0, finish = children.length - 1; + var mid, success = false; + + while (finish - first > 3) + { + mid = Math.floor((finish + first) / 2); + + var i = checkitem(mid); + if (i == 0) i = dir; + if (i == -1) + finish = mid; + else + first = mid; + } + var a = (dir == 1 ? first : finish); + var b = (dir == 1 ? finish : first); + for (var i = b; i != a - dir; i -= dir) + { + if (checkitem(i) == 0) return i; + } + return -1; + } + + + // from an index, decide what the result is + // 0 = match, -1 is lower, 1 is higher + function checkitem(i) + { + var s = getitem(i).toLowerCase().substr(0, text.length); + if (s == text) return 0; + else return (s > text ? -1 : 1); + } + + + // from an index, get its string + // this abstracts over alternates + function getitem(i) + { + for ( ; i >= 0; i--) + { + var s = children[i].firstChild.firstChild.data; + if (s.indexOf(' ') == -1) + return s; + } + return ""; // should never be reached + } +} + +function setSynopsis(filename) { + if (parent.window.synopsis) { + if (parent.window.synopsis.location.replace) { + // In Firefox this avoids adding the change to the history. + parent.window.synopsis.location.replace(filename); + } else { + parent.window.synopsis.location = filename; + } + } +} + +function addMenuItem(html) { + var menu = document.getElementById("page-menu"); + if (menu) { + var btn = menu.firstChild.cloneNode(false); + btn.innerHTML = html; + menu.appendChild(btn); + } +} + +function adjustForFrames() { + var bodyCls; + + if (parent.location.href == window.location.href) { + // not in frames, so add Frames button + addMenuItem("Frames"); + bodyCls = "no-frame"; + } + else { + bodyCls = "in-frame"; + } + addClass(document.body, bodyCls); +} + +function reframe() { + setCookie("haddock-reframe", document.URL); + window.location = "frames.html"; +} + +function postReframe() { + var s = getCookie("haddock-reframe"); + if (s) { + parent.window.main.location = s; + clearCookie("haddock-reframe"); + } +} + +function styles() { + var i, a, es = document.getElementsByTagName("link"), rs = []; + for (i = 0; a = es[i]; i++) { + if(a.rel.indexOf("style") != -1 && a.title) { + rs.push(a); + } + } + return rs; +} + +function addStyleMenu() { + var as = styles(); + var i, a, btns = ""; + for(i=0; a = as[i]; i++) { + btns += "
  • " + + a.title + "
  • " + } + if (as.length > 1) { + var h = "
    " + + "Style ▾" + + "" + + "
    "; + addMenuItem(h); + } +} + +function setActiveStyleSheet(title) { + var as = styles(); + var i, a, found; + for(i=0; a = as[i]; i++) { + a.disabled = true; + // need to do this always, some browsers are edge triggered + if(a.title == title) { + found = a; + } + } + if (found) { + found.disabled = false; + setCookie("haddock-style", title); + } + else { + as[0].disabled = false; + clearCookie("haddock-style"); + } + styleMenu(false); +} + +function resetStyle() { + var s = getCookie("haddock-style"); + if (s) setActiveStyleSheet(s); +} + + +function styleMenu(show) { + var m = document.getElementById('style-menu'); + if (m) toggleShow(m, show); +} + + +function pageLoad() { + addStyleMenu(); + adjustForFrames(); + resetStyle(); + restoreCollapsed(); +} + diff --git a/hslogo-16.png b/hslogo-16.png new file mode 100644 index 0000000000000000000000000000000000000000..0ff8579fbd897417b0d6dad6e920f8882138a7c0 GIT binary patch literal 1684 zcmV;F25b3=P)4Tx0C)j~RL^S@K@|QrZmG~B2wH0nvUrdpNm;9CMbtL^5n^i$+aIn^?(HA4aZWV5ov6ELTdbo0FI&wK{O>*+w4vx20?>!`FrQsdJlnHR>OPy zcd~b_n$otK2Za4V;76L-DzNVtaSB-y0*E}{p()372;bw_^6ZZ}PI-92wGS&j#91PI zKs7DSe@(bk%_Y-7gGe}(^>I=@oY#w#*Bu9GZf3^F5WP>3rn}7Ut74&?PWBFvy`A)a zPP5)V!Xd&78LdA?xQ(9mjMYElVd13a#D+Z_7&Y|xU=_C-srWU*6kiZcC!$nw*)9$7 zn6CX+@=AhmkT}X@VSsa5NKe;HZuq)~1$`#h6R+ZTR#D-3j}vF!)ZOnz+5)dI4jl{{ z44Mr{P!L4~VVJN`K!!XTF*LGrKO?IK8z<8w`3e3jI8lUGNUta*C8 zn(P`s>{pjD=7Kek#B;Fw@hxAK%$F&Q6vg9J^Xf~4by_hu-=A!MJ3Znq&n~srbFGPs zH&&aMXZ>nO`|hf|ljc?VPhR!${AbO?W8x_>CU%PFA&Hm8F7cAsOREdwU~R_;ot1_u z(ruCYB-LPGn!NQdT|ZlRy+(fw^-+`=%+gee_kY4FWHg<*4sZI8+sFJD270UUORdLHO0nA4V) z%{fwsET5CQ>B?eK%uw4yQc~9?*JVo2}ze(;aRcp*ceL#HUJSllrgm5wQKR zQu+C;QrUh^8rFfA`ftFz{YAidi-`aL010qNS#tmY4c7nw4c7reD4Tcy00T@(L_t(I z5sj2vNEA^R$7gqDc6T=2^@fUA2(c`MltuL5<|KW>RWz$&YbU@|M|{$E*8Tu-Ux!w z1Y*Dr&Ubfr&v-nZaaB{3ilRumrjPmk{sZvQEWlW+{o~IH|8)=s6c#X9S5s5d%J z4@)&QH5|xQY-)^L1n0pTRu0Lx9`08YTjTwn^6 z0;b1+aQ@)n;Em$q;=7BBi)v0zj&o^g>0Whp^_^5IbxIUP8C@y9;R?*Ouu}rmfxbU= zwtWVNke-m!=`7bYEhWpcI5#)9qp`8E0lr6IQ)ARL3Ui}Af@grj8aN1=r>Cb+prlzO zNfJs*N_tUm2ZL%5* zPmL2??da$TR904gL(VDAQ-Fv_Dk}Pdw*4T(%*f4MKLRg=4ekMjhe2mW zMFsBwg%ftWT}0kxRaIk1k7qJ8*#cKB;Ft{i`zVIs-Nqge;!!Ld7#O&Qqu7e0sJmP) z$MW*>L$vSB&dxp@iA3U9fo)-7!Czlr{|o7Hv{1oyg3xsu%gn@(b1>$;SM-ZaQ`HV=V0s;lr%d8bd;xY zGwNvm3=Iu=tyXIgtJnf@A(2S@M140N ew{UA~tMxaJq;$xaSSi*30000ldap-client-0.1.0: Pure Haskell LDAP Client Library \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..edcd5a8 --- /dev/null +++ b/index.html @@ -0,0 +1,4 @@ +ldap-client-0.1.0: Pure Haskell LDAP Client Library

    ldap-client-0.1.0: Pure Haskell LDAP Client Library

    ldap-client-0.1.0: Pure Haskell LDAP Client Library

    Pure Haskell LDAP client library implementing (the parts of) RFC 4511.

    \ No newline at end of file diff --git a/ldap-client.haddock b/ldap-client.haddock new file mode 100644 index 0000000000000000000000000000000000000000..df2ff38acc3eaad802bb87c3075f6491d53d8a9b GIT binary patch literal 56754 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 literal 0 HcmV?d00001 diff --git a/mini_Ldap-Asn1-FromAsn1.html b/mini_Ldap-Asn1-FromAsn1.html new file mode 100644 index 0000000..5a1b897 --- /dev/null +++ b/mini_Ldap-Asn1-FromAsn1.html @@ -0,0 +1,4 @@ +Ldap.Asn1.FromAsn1

    Ldap.Asn1.FromAsn1

    \ No newline at end of file diff --git a/mini_Ldap-Asn1-ToAsn1.html b/mini_Ldap-Asn1-ToAsn1.html new file mode 100644 index 0000000..4f67251 --- /dev/null +++ b/mini_Ldap-Asn1-ToAsn1.html @@ -0,0 +1,4 @@ +Ldap.Asn1.ToAsn1

    Ldap.Asn1.ToAsn1

    class ToAsn1 a

    \ No newline at end of file diff --git a/mini_Ldap-Asn1-Type.html b/mini_Ldap-Asn1-Type.html new file mode 100644 index 0000000..8868af8 --- /dev/null +++ b/mini_Ldap-Asn1-Type.html @@ -0,0 +1,4 @@ +Ldap.Asn1.Type

    Ldap.Asn1.Type

    \ No newline at end of file diff --git a/mini_Ldap-Client-Add.html b/mini_Ldap-Client-Add.html new file mode 100644 index 0000000..3e317aa --- /dev/null +++ b/mini_Ldap-Client-Add.html @@ -0,0 +1,4 @@ +Ldap.Client.Add

    Ldap.Client.Add

    \ No newline at end of file diff --git a/mini_Ldap-Client-Bind.html b/mini_Ldap-Client-Bind.html new file mode 100644 index 0000000..7ed621a --- /dev/null +++ b/mini_Ldap-Client-Bind.html @@ -0,0 +1,4 @@ +Ldap.Client.Bind

    Ldap.Client.Bind

    \ No newline at end of file diff --git a/mini_Ldap-Client-Compare.html b/mini_Ldap-Client-Compare.html new file mode 100644 index 0000000..432a0ba --- /dev/null +++ b/mini_Ldap-Client-Compare.html @@ -0,0 +1,4 @@ +Ldap.Client.Compare

    Ldap.Client.Compare

    \ No newline at end of file diff --git a/mini_Ldap-Client-Delete.html b/mini_Ldap-Client-Delete.html new file mode 100644 index 0000000..f046436 --- /dev/null +++ b/mini_Ldap-Client-Delete.html @@ -0,0 +1,4 @@ +Ldap.Client.Delete

    Ldap.Client.Delete

    \ No newline at end of file diff --git a/mini_Ldap-Client-Extended.html b/mini_Ldap-Client-Extended.html new file mode 100644 index 0000000..ebf2d85 --- /dev/null +++ b/mini_Ldap-Client-Extended.html @@ -0,0 +1,4 @@ +Ldap.Client.Extended

    Ldap.Client.Extended

    \ No newline at end of file diff --git a/mini_Ldap-Client-Internal.html b/mini_Ldap-Client-Internal.html new file mode 100644 index 0000000..9229263 --- /dev/null +++ b/mini_Ldap-Client-Internal.html @@ -0,0 +1,4 @@ +Ldap.Client.Internal

    Ldap.Client.Internal

    data Host

    data Ldap

    data Async a

    data Oid

    type AttrList f

    Waiting for Request Completion

    Misc

    type Request

    data Dn

    data Attr

    \ No newline at end of file diff --git a/mini_Ldap-Client-Modify.html b/mini_Ldap-Client-Modify.html new file mode 100644 index 0000000..06ccf0f --- /dev/null +++ b/mini_Ldap-Client-Modify.html @@ -0,0 +1,4 @@ +Ldap.Client.Modify

    Ldap.Client.Modify

    \ No newline at end of file diff --git a/mini_Ldap-Client-Search.html b/mini_Ldap-Client-Search.html new file mode 100644 index 0000000..9d4bb03 --- /dev/null +++ b/mini_Ldap-Client-Search.html @@ -0,0 +1,4 @@ +Ldap.Client.Search

    Ldap.Client.Search

    \ No newline at end of file diff --git a/mini_Ldap-Client.html b/mini_Ldap-Client.html new file mode 100644 index 0000000..7165334 --- /dev/null +++ b/mini_Ldap-Client.html @@ -0,0 +1,4 @@ +Ldap.Client

    Ldap.Client

    data Host

    data Ldap

    data Async a

    Bind

    Search

    Search modifiers

    data Search

    data Mod a

    data Scope

    data Filter

    Modify

    Add

    Delete

    ModifyDn

    Compare

    Extended

    Waiting for completion

    Miscellanous

    data Dn

    data Oid

    type AttrList f

    data Attr

    Re-exports

    data NonEmpty a

    \ No newline at end of file diff --git a/minus.gif b/minus.gif new file mode 100644 index 0000000000000000000000000000000000000000..1deac2fe1a42e35b994f1b855488f392c50f6a89 GIT binary patch literal 56 zcmZ?wbhEHb * { + font-size: 93%; /* 12pt */ +} + +#mini #module-list .caption, +#mini #module-header .caption { + font-size: 125%; /* 15pt */ +} + +#mini #interface h1, +#mini #interface h2, +#mini #interface h3, +#mini #interface h4 { + font-size: 109%; /* 13pt */ + margin: 1em 0 0; +} + +#mini #interface .top, +#mini #interface .src { + margin: 0; +} + +#mini #module-list ul { + list-style: none; + margin: 0; +} + +#alphabet ul { + list-style: none; + padding: 0; + margin: 0.5em 0 0; + text-align: center; +} + +#alphabet li { + display: inline; + margin: 0 0.25em; +} + +#alphabet a { + font-weight: bold; +} + +#index .caption, +#module-list .caption { font-size: 131%; /* 17pt */ } + +#index table { + margin-left: 2em; +} + +#index .src { + font-weight: bold; +} +#index .alt { + font-size: 77%; /* 10pt */ + font-style: italic; + padding-left: 2em; +} + +#index td + td { + padding-left: 1em; +} + +#module-list ul { + list-style: none; + margin: 0 0 0 2em; +} + +#module-list li { + clear: right; +} + +#module-list span.collapser, +#module-list span.expander { + background-position: 0 0.3em; +} + +#module-list .package { + float: right; +} + +/* @end */ diff --git a/plus.gif b/plus.gif new file mode 100644 index 0000000000000000000000000000000000000000..2d15c14173d23f664b955cd24f51c82f5f09d91d GIT binary patch literal 59 zcmZ?wbhEHbgbBX M^XE!9f*2UA0nx1yDgXcg literal 0 HcmV?d00001 diff --git a/src/Ldap-Asn1-FromAsn1.html b/src/Ldap-Asn1-FromAsn1.html new file mode 100644 index 0000000..b526d8a --- /dev/null +++ b/src/Ldap-Asn1-FromAsn1.html @@ -0,0 +1,389 @@ + + + + + +src/Ldap/Asn1/FromAsn1.hs + + + +
    {-# LANGUAGE CPP #-}
    +module Ldap.Asn1.FromAsn1
    +  ( FromAsn1(..)
    +  , Parser
    +  , parseAsn1
    +  , parse
    +  , next
    +  ) where
    +
    +#if __GLASGOW_HASKELL__ >= 710
    +import           Control.Applicative (Alternative(..), liftA2, optional)
    +#else
    +import           Control.Applicative (Applicative(..), Alternative(..), liftA2, optional)
    +#endif
    +import           Control.Monad (MonadPlus(..), (>=>), guard)
    +import           Data.ASN1.Types (ASN1)
    +import qualified Data.ASN1.Types as Asn1
    +import           Data.Foldable (asum)
    +import           Data.List.NonEmpty (some1)
    +import qualified Data.Text.Encoding as Text
    +
    +import           Ldap.Asn1.Type
    +
    +{-# ANN module "HLint: ignore Use const" #-}
    +{-# ANN module "HLint: ignore Avoid lambda" #-}
    +
    +
    +class FromAsn1 a where
    +  fromAsn1 :: Parser [ASN1] a
    +
    +{- |
    +@
    +LDAPMessage ::= SEQUENCE {
    +     messageID       MessageID,
    +     protocolOp      CHOICE {
    +          bindRequest           BindRequest,
    +          bindResponse          BindResponse,
    +          unbindRequest         UnbindRequest,
    +          searchRequest         SearchRequest,
    +          searchResEntry        SearchResultEntry,
    +          searchResDone         SearchResultDone,
    +          searchResRef          SearchResultReference,
    +          addRequest            AddRequest,
    +          addResponse           AddResponse,
    +          ... },
    +     controls       [0] Controls OPTIONAL }
    +@
    +-}
    +instance FromAsn1 op =>  FromAsn1 (LdapMessage op) where
    +  fromAsn1 = do
    +    Asn1.Start Asn1.Sequence <- next
    +    i  <- fromAsn1
    +    op <- fromAsn1
    +    Asn1.End Asn1.Sequence <- next
    +    return (LdapMessage i op Nothing)
    +
    +{- |
    +@
    +MessageID ::= INTEGER (0 ..  maxInt)
    +@
    +-}
    +instance FromAsn1 Id where
    +  fromAsn1 = do
    +    Asn1.IntVal i <- next
    +    return (Id (fromIntegral i))
    +
    +{- |
    +@
    +LDAPString ::= OCTET STRING -- UTF-8 encoded,
    +@
    +-}
    +instance FromAsn1 LdapString where
    +  fromAsn1 = do
    +    Asn1.OctetString s <- next
    +    case Text.decodeUtf8' s of
    +      Right t -> return (LdapString t)
    +      Left  _ -> empty
    +
    +{- |
    +@
    +LDAPOID ::= OCTET STRING -- Constrained to \<numericoid\>
    +@
    +-}
    +instance FromAsn1 LdapOid where
    +  fromAsn1 = do
    +    Asn1.OctetString s <- next
    +    return (LdapOid s)
    +
    +{- |
    +@
    +LDAPDN ::= LDAPString
    +@
    +-}
    +instance FromAsn1 LdapDn where
    +  fromAsn1 = fmap LdapDn fromAsn1
    +
    +{- |
    +@
    +AttributeDescription ::= LDAPString
    +@
    +-}
    +instance FromAsn1 AttributeDescription where
    +  fromAsn1 = fmap AttributeDescription fromAsn1
    +
    +{- |
    +@
    +AttributeValue ::= OCTET STRING
    +@
    +-}
    +instance FromAsn1 AttributeValue where
    +  fromAsn1 = do
    +    Asn1.OctetString s <- next
    +    return (AttributeValue s)
    +
    +{- |
    +@
    +PartialAttribute ::= SEQUENCE {
    +     type       AttributeDescription,
    +     vals       SET OF value AttributeValue }
    +@
    +-}
    +instance FromAsn1 PartialAttribute where
    +  fromAsn1 = do
    +    Asn1.Start Asn1.Sequence <- next
    +    d  <- fromAsn1
    +    Asn1.Start Asn1.Set <- next
    +    vs <- many fromAsn1
    +    Asn1.End Asn1.Set <- next
    +    Asn1.End Asn1.Sequence <- next
    +    return (PartialAttribute d vs)
    +
    +{- |
    +@
    +LDAPResult ::= SEQUENCE {
    +     resultCode         ENUMERATED {
    +          success                      (0),
    +          operationsError              (1),
    +          protocolError                (2),
    +          timeLimitExceeded            (3),
    +          sizeLimitExceeded            (4),
    +          compareFalse                 (5),
    +          compareTrue                  (6),
    +          authMethodNotSupported       (7),
    +          strongerAuthRequired         (8),
    +          -- 9 reserved --
    +          referral                     (10),
    +          adminLimitExceeded           (11),
    +          unavailableCriticalExtension (12),
    +          confidentialityRequired      (13),
    +          saslBindInProgress           (14),
    +          noSuchAttribute              (16),
    +          undefinedAttributeType       (17),
    +          inappropriateMatching        (18),
    +          constraintViolation          (19),
    +          attributeOrValueExists       (20),
    +          invalidAttributeSyntax       (21),
    +          -- 22-31 unused --
    +          noSuchObject                 (32),
    +          aliasProblem                 (33),
    +          invalidDNSyntax              (34),
    +          -- 35 reserved for undefined isLeaf --
    +          aliasDereferencingProblem    (36),
    +          -- 37-47 unused --
    +          inappropriateAuthentication  (48),
    +          invalidCredentials           (49),
    +          insufficientAccessRights     (50),
    +          busy                         (51),
    +          unavailable                  (52),
    +          unwillingToPerform           (53),
    +          loopDetect                   (54),
    +          -- 55-63 unused --
    +          namingViolation              (64),
    +          objectClassViolation         (65),
    +          notAllowedOnNonLeaf          (66),
    +          notAllowedOnRDN              (67),
    +          entryAlreadyExists           (68),
    +          objectClassModsProhibited    (69),
    +          -- 70 reserved for CLDAP --
    +          affectsMultipleDSAs          (71),
    +          -- 72-79 unused --
    +          other                        (80),
    +          ...  },
    +     matchedDN          LDAPDN,
    +     diagnosticMessage  LDAPString,
    +     referral           [3] Referral OPTIONAL }
    +@
    +-}
    +instance FromAsn1 LdapResult where
    +  fromAsn1 = do
    +    resultCode <- do
    +      Asn1.Enumerated x <- next
    +      case x of
    +        0  -> pure Success
    +        1  -> pure OperationError
    +        2  -> pure ProtocolError
    +        3  -> pure TimeLimitExceeded
    +        4  -> pure SizeLimitExceeded
    +        5  -> pure CompareFalse
    +        6  -> pure CompareTrue
    +        7  -> pure AuthMethodNotSupported
    +        8  -> pure StrongerAuthRequired
    +        10 -> pure Referral
    +        11 -> pure AdminLimitExceeded
    +        12 -> pure UnavailableCriticalExtension
    +        13 -> pure ConfidentialityRequired
    +        14 -> pure SaslBindInProgress
    +        16 -> pure NoSuchAttribute
    +        17 -> pure UndefinedAttributeType
    +        18 -> pure InappropriateMatching
    +        19 -> pure ConstraintViolation
    +        20 -> pure AttributeOrValueExists
    +        21 -> pure InvalidAttributeSyntax
    +        32 -> pure NoSuchObject
    +        33 -> pure AliasProblem
    +        34 -> pure InvalidDNSyntax
    +        36 -> pure AliasDereferencingProblem
    +        48 -> pure InappropriateAuthentication
    +        49 -> pure InvalidCredentials
    +        50 -> pure InsufficientAccessRights
    +        51 -> pure Busy
    +        52 -> pure Unavailable
    +        53 -> pure UnwillingToPerform
    +        54 -> pure LoopDetect
    +        64 -> pure NamingViolation
    +        65 -> pure ObjectClassViolation
    +        66 -> pure NotAllowedOnNonLeaf
    +        67 -> pure NotAllowedOnRDN
    +        68 -> pure EntryAlreadyExists
    +        69 -> pure ObjectClassModsProhibited
    +        71 -> pure AffectsMultipleDSAs
    +        80 -> pure Other
    +        _  -> empty
    +    matchedDn  <- fromAsn1
    +    diagnosticMessage
    +               <- fromAsn1
    +    referral   <- optional $ do
    +      Asn1.Start (Asn1.Container Asn1.Context 0) <- next
    +      x <- fromAsn1
    +      Asn1.End (Asn1.Container Asn1.Context 0) <- next
    +      return x
    +    return (LdapResult resultCode matchedDn diagnosticMessage referral)
    +
    +{- |
    +@
    +Referral ::= SEQUENCE SIZE (1..MAX) OF uri URI
    +@
    +-}
    +instance FromAsn1 ReferralUris where
    +  fromAsn1 = do
    +    Asn1.Start Asn1.Sequence <- next
    +    xs <- some1 fromAsn1
    +    Asn1.End Asn1.Sequence <- next
    +    return (ReferralUris xs)
    +
    +{- |
    +@
    +URI ::= LDAPString
    +@
    +-}
    +instance FromAsn1 Uri where
    +  fromAsn1 = fmap Uri fromAsn1
    +
    +{- |
    +@
    +BindResponse ::= [APPLICATION 1] SEQUENCE {
    +     COMPONENTS OF LDAPResult,
    +     serverSaslCreds    [7] OCTET STRING OPTIONAL }
    +@
    +
    +@
    +SearchResultEntry ::= [APPLICATION 4] SEQUENCE {
    +     objectName      LDAPDN,
    +     attributes      PartialAttributeList }
    +@
    +
    +@
    +SearchResultDone ::= [APPLICATION 5] LDAPResult
    +@
    +
    +@
    +ModifyResponse ::= [APPLICATION 7] LDAPResult
    +@
    +
    +@
    +AddResponse ::= [APPLICATION 9] LDAPResult
    +@
    +
    +@
    +DelResponse ::= [APPLICATION 11] LDAPResult
    +@
    +
    +@
    +CompareResponse ::= [APPLICATION 15] LDAPResult
    +@
    +-}
    +instance FromAsn1 ProtocolServerOp where
    +  fromAsn1 = asum
    +    [ fmap (\res -> BindResponse res Nothing) (app 1)
    +    , fmap (uncurry SearchResultEntry) (app 4)
    +    , fmap SearchResultDone (app 5)
    +    , fmap ModifyResponse (app 7)
    +    , fmap AddResponse (app 9)
    +    , fmap DeleteResponse (app 11)
    +    , fmap ModifyDnResponse (app 13)
    +    , fmap CompareResponse (app 15)
    +    , do
    +      Asn1.Start (Asn1.Container Asn1.Application 24) <- next
    +      res <- fromAsn1
    +      name <- optional $ do
    +        Asn1.Other Asn1.Context 0 s <- next
    +        return s
    +      value <- optional $ do
    +        Asn1.Other Asn1.Context 1 s <- next
    +        return s
    +      Asn1.End (Asn1.Container Asn1.Application 24) <- next
    +      return (ExtendedResponse res (fmap LdapOid name) value)
    +    ]
    +   where
    +    app l = do
    +      Asn1.Start (Asn1.Container Asn1.Application x) <- next
    +      guard (x == l)
    +      res <- fromAsn1
    +      Asn1.End (Asn1.Container Asn1.Application y) <- next
    +      guard (y == l)
    +      return res
    +
    +{- |
    +@
    +PartialAttributeList ::= SEQUENCE OF partialAttribute PartialAttribute
    +@
    +-}
    +instance FromAsn1 PartialAttributeList where
    +  fromAsn1 = do
    +    Asn1.Start Asn1.Sequence <- next
    +    xs <- many fromAsn1
    +    Asn1.End Asn1.Sequence <- next
    +    return (PartialAttributeList xs)
    +
    +instance (FromAsn1 a, FromAsn1 b) => FromAsn1 (a, b) where
    +  fromAsn1 = liftA2 (,) fromAsn1 fromAsn1
    +
    +
    +newtype Parser s a = Parser { unParser :: s -> Maybe (s, a) }
    +
    +instance Functor (Parser s) where
    +  fmap f (Parser g) = Parser (fmap (fmap f) . g)
    +
    +instance Applicative (Parser s) where
    +  pure x = Parser (\s -> pure (s, x))
    +  Parser mf <*> Parser mx = Parser $ \s -> do
    +    (s', f)  <- mf s
    +    (s'', x) <- mx s'
    +    pure (s'', f x)
    +
    +instance Alternative (Parser s) where
    +  empty = Parser (\_ -> empty)
    +  Parser ma <|> Parser mb =
    +    Parser (\s -> ma s <|> mb s)
    +
    +instance Monad (Parser s) where
    +  return x = Parser (\s -> return (s, x))
    +  Parser mx >>= k =
    +    Parser (mx >=> \(s', x) -> unParser (k x) s')
    +  fail _ = empty
    +
    +instance MonadPlus (Parser s) where
    +  mzero = Parser (\_ -> mzero)
    +  Parser ma `mplus` Parser mb =
    +    Parser (\s -> ma s `mplus` mb s)
    +
    +parseAsn1 :: FromAsn1 a => [ASN1] -> Maybe ([ASN1], a)
    +parseAsn1 = parse fromAsn1
    +
    +parse :: Parser s a -> s -> Maybe (s, a)
    +parse = unParser
    +
    +next :: Parser [s] s
    +next = Parser (\s -> case s of [] -> Nothing; x : xs -> Just (xs, x))
    +
    + diff --git a/src/Ldap-Asn1-ToAsn1.html b/src/Ldap-Asn1-ToAsn1.html new file mode 100644 index 0000000..90e7770 --- /dev/null +++ b/src/Ldap-Asn1-ToAsn1.html @@ -0,0 +1,432 @@ + + + + + +src/Ldap/Asn1/ToAsn1.hs + + + +
    module Ldap.Asn1.ToAsn1
    +  ( ToAsn1(toAsn1)
    +  ) where
    +
    +import           Data.ASN1.Types (ASN1, ASN1Class, ASN1Tag, ASN1ConstructionType)
    +import qualified Data.ASN1.Types as Asn1
    +import           Data.ByteString (ByteString)
    +import           Data.Foldable (fold, foldMap)
    +import           Data.List.NonEmpty (NonEmpty)
    +import           Data.Maybe (Maybe, maybe)
    +import           Data.Monoid (Endo(Endo), (<>), mempty)
    +import qualified Data.Text.Encoding as Text
    +import           Prelude (Integer, (.), fromIntegral)
    +
    +import           Ldap.Asn1.Type
    +
    +
    +class ToAsn1 a where
    +  toAsn1 :: a -> Endo [ASN1]
    +
    +{- |
    +@
    +LDAPMessage ::= SEQUENCE {
    +     messageID       MessageID,
    +     protocolOp      CHOICE {
    +          bindRequest           BindRequest,
    +          bindResponse          BindResponse,
    +          unbindRequest         UnbindRequest,
    +          searchRequest         SearchRequest,
    +          searchResEntry        SearchResultEntry,
    +          searchResDone         SearchResultDone,
    +          searchResRef          SearchResultReference,
    +          addRequest            AddRequest,
    +          addResponse           AddResponse,
    +          ... },
    +     controls       [0] Controls OPTIONAL }
    +@
    +-}
    +instance ToAsn1 op => ToAsn1 (LdapMessage op) where
    +  toAsn1 (LdapMessage i op mc) =
    +    sequence (toAsn1 i <> toAsn1 op <> maybe mempty (context 0 . toAsn1) mc)
    +
    +{- |
    +@
    +MessageID ::= INTEGER (0 ..  maxInt)
    +@
    +-}
    +instance ToAsn1 Id where
    +  toAsn1 (Id i) = single (Asn1.IntVal (fromIntegral i))
    +
    +{- |
    +@
    +LDAPString ::= OCTET STRING -- UTF-8 encoded
    +@
    +-}
    +instance ToAsn1 LdapString where
    +  toAsn1 (LdapString s) = single (Asn1.OctetString (Text.encodeUtf8 s))
    +
    +{- |
    +@
    +LDAPOID ::= OCTET STRING -- Constrained to \<numericoid\>
    +@
    +-}
    +instance ToAsn1 LdapOid where
    +  toAsn1 (LdapOid s) = single (Asn1.OctetString s)
    +
    +{- |
    +@
    +LDAPDN ::= LDAPString -- Constrained to \<distinguishedName\>
    +@
    +-}
    +instance ToAsn1 LdapDn where
    +  toAsn1 (LdapDn s) = toAsn1 s
    +
    +{- |
    +@
    +RelativeLDAPDN ::= LDAPString -- Constrained to \<name-component\>
    +@
    +-}
    +instance ToAsn1 RelativeLdapDn where
    +  toAsn1 (RelativeLdapDn s) = toAsn1 s
    +
    +{- |
    +@
    +AttributeDescription ::= LDAPString
    +@
    +-}
    +instance ToAsn1 AttributeDescription where
    +  toAsn1 (AttributeDescription s) = toAsn1 s
    +
    +{- |
    +@
    +AttributeValue ::= OCTET STRING
    +@
    +-}
    +instance ToAsn1 AttributeValue where
    +  toAsn1 (AttributeValue s) = single (Asn1.OctetString s)
    +
    +{- |
    +@
    +AttributeValueAssertion ::= SEQUENCE {
    +     attributeDesc   AttributeDescription,
    +     assertionValue  AssertionValue }
    +@
    +-}
    +instance ToAsn1 AttributeValueAssertion where
    +  toAsn1 (AttributeValueAssertion d v) = toAsn1 d <> toAsn1 v
    +
    +{- |
    +@
    +AssertionValue ::= OCTET STRING
    +@
    +-}
    +instance ToAsn1 AssertionValue where
    +  toAsn1 (AssertionValue s) = single (Asn1.OctetString s)
    +
    +
    +{- |
    +@
    +PartialAttribute ::= SEQUENCE {
    +     type       AttributeDescription,
    +     vals       SET OF value AttributeValue }
    +@
    +-}
    +instance ToAsn1 PartialAttribute where
    +  toAsn1 (PartialAttribute d xs) = sequence (toAsn1 d <> set (toAsn1 xs))
    +
    +{- |
    +@
    +Attribute ::= PartialAttribute(WITH COMPONENTS {
    +     ...,
    +     vals (SIZE(1..MAX))})
    +@
    +-}
    +instance ToAsn1 Attribute where
    +  toAsn1 (Attribute d xs) = sequence (toAsn1 d <> set (toAsn1 xs))
    +
    +{- |
    +@
    +MatchingRuleId ::= LDAPString
    +@
    +-}
    +instance ToAsn1 MatchingRuleId where
    +  toAsn1 (MatchingRuleId s) = toAsn1 s
    +
    +{- |
    +@
    +Controls ::= SEQUENCE OF control Control
    +@
    +-}
    +instance ToAsn1 Controls where
    +  toAsn1 (Controls cs) = sequence (toAsn1 cs)
    +
    +{- |
    +@
    +Control ::= SEQUENCE {
    +     controlType             LDAPOID,
    +     criticality             BOOLEAN DEFAULT FALSE,
    +     controlValue            OCTET STRING OPTIONAL }
    +@
    +-}
    +instance ToAsn1 Control where
    +  toAsn1 (Control t c v) =
    +    sequence (fold
    +      [ toAsn1 t
    +      , single (Asn1.Boolean c)
    +      , maybe mempty (single . Asn1.OctetString) v
    +      ])
    +
    +{- |
    +@
    +BindRequest ::= [APPLICATION 0] SEQUENCE {
    +     version                 INTEGER (1 ..  127),
    +     name                    LDAPDN,
    +     authentication          AuthenticationChoice }
    +@
    +
    +@
    +UnbindRequest ::= [APPLICATION 2] NULL
    +@
    +
    +@
    +SearchRequest ::= [APPLICATION 3] SEQUENCE {
    +     baseObject      LDAPDN,
    +     scope           ENUMERATED {
    +          baseObject              (0),
    +          singleLevel             (1),
    +          wholeSubtree            (2),
    +          ...  },
    +     derefAliases    ENUMERATED {
    +          neverDerefAliases       (0),
    +          derefInSearching        (1),
    +          derefFindingBaseObj     (2),
    +          derefAlways             (3) },
    +     sizeLimit       INTEGER (0 ..  maxInt),
    +     timeLimit       INTEGER (0 ..  maxInt),
    +     typesOnly       BOOLEAN,
    +     filter          Filter,
    +     attributes      AttributeSelection }
    +@
    +
    +@
    +ModifyRequest ::= [APPLICATION 6] SEQUENCE {
    +     object          LDAPDN,
    +     changes         SEQUENCE OF change SEQUENCE {
    +          operation       ENUMERATED {
    +               add     (0),
    +               delete  (1),
    +               replace (2),
    +               ...  },
    +          modification    PartialAttribute } }
    +@
    +
    +@
    +AddRequest ::= [APPLICATION 8] SEQUENCE {
    +     entry           LDAPDN,
    +     attributes      AttributeList }
    +@
    +
    +@
    +DelRequest ::= [APPLICATION 10] LDAPDN
    +@
    +
    +@
    +ModifyDNRequest ::= [APPLICATION 12] SEQUENCE {
    +     entry           LDAPDN,
    +     newrdn          RelativeLDAPDN,
    +     deleteoldrdn    BOOLEAN,
    +     newSuperior     [0] LDAPDN OPTIONAL }
    +@
    +
    +@
    +CompareRequest ::= [APPLICATION 14] SEQUENCE {
    +     entry           LDAPDN,
    +     ava             AttributeValueAssertion }
    +@
    +
    +@
    +ExtendedRequest ::= [APPLICATION 23] SEQUENCE {
    +     requestName      [0] LDAPOID,
    +     requestValue     [1] OCTET STRING OPTIONAL }
    +@
    +-}
    +instance ToAsn1 ProtocolClientOp where
    +  toAsn1 (BindRequest v n a) =
    +    application 0 (single (Asn1.IntVal (fromIntegral v)) <> toAsn1 n <> toAsn1 a)
    +  toAsn1 UnbindRequest =
    +    other Asn1.Application 2 mempty
    +  toAsn1 (SearchRequest bo s da sl tl to f a) =
    +    application 3 (fold
    +      [ toAsn1 bo
    +      , enum s'
    +      , enum da'
    +      , single (Asn1.IntVal (fromIntegral sl))
    +      , single (Asn1.IntVal (fromIntegral tl))
    +      , single (Asn1.Boolean to)
    +      , toAsn1 f
    +      , toAsn1 a
    +      ])
    +   where
    +    s' = case s of
    +      BaseObject   -> 0
    +      SingleLevel  -> 1
    +      WholeSubtree -> 2
    +    da' = case da of
    +      NeverDerefAliases      -> 0
    +      DerefInSearching       -> 1
    +      DerefFindingBaseObject -> 2
    +      DerefAlways            -> 3
    +  toAsn1 (ModifyRequest dn xs) =
    +    application 6 (fold
    +      [ toAsn1 dn
    +      , sequence (foldMap (\(op, pa) -> sequence (enum (case op of
    +          Add     -> 0
    +          Delete  -> 1
    +          Replace -> 2) <> toAsn1 pa)) xs)
    +      ])
    +  toAsn1 (AddRequest dn as) =
    +    application 8 (toAsn1 dn <> toAsn1 as)
    +  toAsn1 (DeleteRequest (LdapDn (LdapString dn))) =
    +    other Asn1.Application 10 (Text.encodeUtf8 dn)
    +  toAsn1 (ModifyDnRequest dn rdn del new) =
    +    application 12 (fold
    +      [ toAsn1 dn
    +      , toAsn1 rdn
    +      , single (Asn1.Boolean del)
    +      , maybe mempty
    +              (\(LdapDn (LdapString dn')) -> other Asn1.Context 0 (Text.encodeUtf8 dn'))
    +              new
    +      ])
    +  toAsn1 (CompareRequest dn av) =
    +    application 14 (toAsn1 dn <> sequence (toAsn1 av))
    +  toAsn1 (ExtendedRequest (LdapOid oid) mv) =
    +    application 23 (fold
    +     [ other Asn1.Context 0 oid
    +     , maybe mempty (other Asn1.Context 1) mv
    +     ])
    +
    +{- |
    +@
    +AuthenticationChoice ::= CHOICE {
    +     simple                  [0] OCTET STRING,
    +     ...  }
    +@
    +-}
    +instance ToAsn1 AuthenticationChoice where
    +  toAsn1 (Simple s) = other Asn1.Context 0 s
    +
    +{- |
    +@
    +AttributeSelection ::= SEQUENCE OF selector LDAPString
    +@
    +-}
    +instance ToAsn1 AttributeSelection where
    +  toAsn1 (AttributeSelection as) = sequence (toAsn1 as)
    +
    +{- |
    +@
    +Filter ::= CHOICE {
    +     and             [0] SET SIZE (1..MAX) OF filter Filter,
    +     or              [1] SET SIZE (1..MAX) OF filter Filter,
    +     not             [2] Filter,
    +     equalityMatch   [3] AttributeValueAssertion,
    +     substrings      [4] SubstringFilter,
    +     greaterOrEqual  [5] AttributeValueAssertion,
    +     lessOrEqual     [6] AttributeValueAssertion,
    +     present         [7] AttributeDescription,
    +     approxMatch     [8] AttributeValueAssertion,
    +     extensibleMatch [9] MatchingRuleAssertion,
    +     ...  }
    +@
    +-}
    +instance ToAsn1 Filter where
    +  toAsn1 f = case f of
    +    And xs            -> context 0 (toAsn1 xs)
    +    Or xs             -> context 1 (toAsn1 xs)
    +    Not x             -> context 2 (toAsn1 x)
    +    EqualityMatch x   -> context 3 (toAsn1 x)
    +    Substrings x      -> context 4 (toAsn1 x)
    +    GreaterOrEqual x  -> context 5 (toAsn1 x)
    +    LessOrEqual x     -> context 6 (toAsn1 x)
    +    Present (AttributeDescription (LdapString x))
    +                      -> other Asn1.Context 7 (Text.encodeUtf8 x)
    +    ApproxMatch x     -> context 8 (toAsn1 x)
    +    ExtensibleMatch x -> context 9 (toAsn1 x)
    +
    +{- |
    +@
    +SubstringFilter ::= SEQUENCE {
    +     type           AttributeDescription,
    +     substrings     SEQUENCE SIZE (1..MAX) OF substring CHOICE {
    +          initial [0] AssertionValue,  -- can occur at most once
    +          any     [1] AssertionValue,
    +          final   [2] AssertionValue } -- can occur at most once
    +     }
    +@
    +-}
    +instance ToAsn1 SubstringFilter where
    +  toAsn1 (SubstringFilter ad ss) =
    +    toAsn1 ad <> sequence (foldMap (\s -> case s of
    +      Initial (AssertionValue v) -> other Asn1.Context 0 v
    +      Any (AssertionValue v)     -> other Asn1.Context 1 v
    +      Final (AssertionValue v)   -> other Asn1.Context 2 v) ss)
    +
    +{- |
    +@
    +MatchingRuleAssertion ::= SEQUENCE {
    +     matchingRule    [1] MatchingRuleId OPTIONAL,
    +     type            [2] AttributeDescription OPTIONAL,
    +     matchValue      [3] AssertionValue,
    +     dnAttributes    [4] BOOLEAN DEFAULT FALSE }
    +@
    +-}
    +instance ToAsn1 MatchingRuleAssertion where
    +  toAsn1 (MatchingRuleAssertion mmr mad av b) = sequence (fold
    +    [ context 1 (optional mmr)
    +    , context 2 (optional mad)
    +    , context 3 (toAsn1 av)
    +    , context 4 (single (Asn1.Boolean b))
    +    ])
    +
    +{- |
    +@
    +AttributeList ::= SEQUENCE OF attribute Attribute
    +@
    +-}
    +instance ToAsn1 AttributeList where
    +  toAsn1 (AttributeList xs) = sequence (toAsn1 xs)
    +
    +instance ToAsn1 a => ToAsn1 [a] where
    +  toAsn1 = foldMap toAsn1
    +
    +instance ToAsn1 a => ToAsn1 (NonEmpty a) where
    +  toAsn1 = foldMap toAsn1
    +
    +sequence :: Endo [ASN1] -> Endo [ASN1]
    +sequence = construction Asn1.Sequence
    +
    +set :: Endo [ASN1] -> Endo [ASN1]
    +set = construction Asn1.Set
    +
    +application :: ASN1Tag -> Endo [ASN1] -> Endo [ASN1]
    +application = construction . Asn1.Container Asn1.Application
    +
    +context :: ASN1Tag -> Endo [ASN1] -> Endo [ASN1]
    +context = construction . Asn1.Container Asn1.Context
    +
    +construction :: ASN1ConstructionType -> Endo [ASN1] -> Endo [ASN1]
    +construction t x = single (Asn1.Start t) <> x <> single (Asn1.End t)
    +
    +other :: ASN1Class -> ASN1Tag -> ByteString -> Endo [ASN1]
    +other c t = single . Asn1.Other c t
    +
    +optional :: ToAsn1 a => Maybe a -> Endo [ASN1]
    +optional = maybe mempty toAsn1
    +
    +enum :: Integer -> Endo [ASN1]
    +enum = single . Asn1.Enumerated
    +
    +single :: a -> Endo [a]
    +single x = Endo (x :)
    +
    + diff --git a/src/Ldap-Asn1-Type.html b/src/Ldap-Asn1-Type.html new file mode 100644 index 0000000..26e7fb2 --- /dev/null +++ b/src/Ldap-Asn1-Type.html @@ -0,0 +1,202 @@ + + + + + +src/Ldap/Asn1/Type.hs + + + +
    module Ldap.Asn1.Type where
    +
    +import Data.ByteString (ByteString)
    +import Data.Int (Int8, Int32)
    +import Data.List.NonEmpty (NonEmpty)
    +import Data.Text (Text)
    +
    +
    +data LdapMessage op = LdapMessage
    +  { ldapMessageId       :: !Id
    +  , ldapMessageOp       :: !op
    +  , ldapMessageControls :: !(Maybe Controls)
    +  } deriving (Show, Eq, Ord)
    +
    +newtype Id = Id { unId :: Int32 }
    +    deriving (Show, Eq, Ord)
    +
    +data ProtocolClientOp =
    +    BindRequest Int8 LdapDn AuthenticationChoice
    +  | UnbindRequest
    +  | SearchRequest LdapDn Scope DerefAliases Int32 Int32 Bool Filter AttributeSelection
    +  | ModifyRequest LdapDn [(Operation, PartialAttribute)]
    +  | AddRequest LdapDn AttributeList
    +  | DeleteRequest LdapDn
    +  | ModifyDnRequest LdapDn RelativeLdapDn Bool (Maybe LdapDn)
    +  | CompareRequest LdapDn AttributeValueAssertion
    +  | ExtendedRequest LdapOid (Maybe ByteString)
    +    deriving (Show, Eq, Ord)
    +
    +data ProtocolServerOp =
    +    BindResponse LdapResult (Maybe ByteString)
    +  | SearchResultEntry LdapDn PartialAttributeList
    +  | SearchResultReference (NonEmpty Uri)
    +  | SearchResultDone (LdapResult)
    +  | ModifyResponse LdapResult
    +  | AddResponse LdapResult
    +  | DeleteResponse LdapResult
    +  | ModifyDnResponse LdapResult
    +  | CompareResponse LdapResult
    +  | ExtendedResponse LdapResult (Maybe LdapOid) (Maybe ByteString)
    +    deriving (Show, Eq, Ord)
    +
    +data AuthenticationChoice = Simple ByteString
    +    deriving (Show, Eq, Ord)
    +
    +data Scope =
    +    BaseObject
    +  | SingleLevel
    +  | WholeSubtree
    +    deriving (Show, Eq, Ord)
    +
    +data DerefAliases =
    +    NeverDerefAliases
    +  | DerefInSearching
    +  | DerefFindingBaseObject
    +  | DerefAlways
    +    deriving (Show, Eq, Ord)
    +
    +data Filter =
    +    And (NonEmpty Filter)
    +  | Or (NonEmpty Filter)
    +  | Not Filter
    +  | EqualityMatch AttributeValueAssertion
    +  | Substrings SubstringFilter
    +  | GreaterOrEqual AttributeValueAssertion
    +  | LessOrEqual AttributeValueAssertion
    +  | Present AttributeDescription
    +  | ApproxMatch AttributeValueAssertion
    +  | ExtensibleMatch MatchingRuleAssertion
    +    deriving (Show, Eq, Ord)
    +
    +data SubstringFilter = SubstringFilter AttributeDescription (NonEmpty Substring)
    +    deriving (Show, Eq, Ord)
    +
    +data Substring =
    +    Initial AssertionValue
    +  | Any AssertionValue
    +  | Final AssertionValue
    +    deriving (Show, Eq, Ord)
    +
    +data MatchingRuleAssertion = MatchingRuleAssertion (Maybe MatchingRuleId) (Maybe AttributeDescription) AssertionValue Bool
    +    deriving (Show, Eq, Ord)
    +
    +newtype MatchingRuleId = MatchingRuleId LdapString
    +    deriving (Show, Eq, Ord)
    +
    +newtype AttributeSelection = AttributeSelection [LdapString]
    +    deriving (Show, Eq, Ord)
    +
    +newtype AttributeList = AttributeList [Attribute]
    +    deriving (Show, Eq, Ord)
    +
    +newtype PartialAttributeList = PartialAttributeList [PartialAttribute]
    +    deriving (Show, Eq, Ord)
    +
    +newtype Controls = Controls [Control]
    +    deriving (Show, Eq, Ord)
    +
    +data Control = Control LdapOid Bool (Maybe ByteString)
    +    deriving (Show, Eq, Ord)
    +
    +data LdapResult = LdapResult ResultCode LdapDn LdapString (Maybe ReferralUris)
    +    deriving (Show, Eq, Ord)
    +
    +data ResultCode =
    +    Success
    +  | OperationError
    +  | ProtocolError
    +  | TimeLimitExceeded
    +  | SizeLimitExceeded
    +  | CompareFalse
    +  | CompareTrue
    +  | AuthMethodNotSupported
    +  | StrongerAuthRequired
    +  | Referral
    +  | AdminLimitExceeded
    +  | UnavailableCriticalExtension
    +  | ConfidentialityRequired
    +  | SaslBindInProgress
    +  | NoSuchAttribute
    +  | UndefinedAttributeType
    +  | InappropriateMatching
    +  | ConstraintViolation
    +  | AttributeOrValueExists
    +  | InvalidAttributeSyntax
    +  | NoSuchObject
    +  | AliasProblem
    +  | InvalidDNSyntax
    +  | AliasDereferencingProblem
    +  | InappropriateAuthentication
    +  | InvalidCredentials
    +  | InsufficientAccessRights
    +  | Busy
    +  | Unavailable
    +  | UnwillingToPerform
    +  | LoopDetect
    +  | NamingViolation
    +  | ObjectClassViolation
    +  | NotAllowedOnNonLeaf
    +  | NotAllowedOnRDN
    +  | EntryAlreadyExists
    +  | ObjectClassModsProhibited
    +  | AffectsMultipleDSAs
    +  | Other
    +    deriving (Show, Eq, Ord)
    +
    +newtype AttributeDescription = AttributeDescription LdapString
    +    deriving (Show, Eq, Ord)
    +
    +newtype AttributeValue = AttributeValue ByteString
    +    deriving (Show, Eq, Ord)
    +
    +data AttributeValueAssertion = AttributeValueAssertion AttributeDescription AssertionValue
    +    deriving (Show, Eq, Ord)
    +
    +newtype AssertionValue = AssertionValue ByteString
    +    deriving (Show, Eq, Ord)
    +
    +data Attribute = Attribute AttributeDescription (NonEmpty AttributeValue)
    +    deriving (Show, Eq, Ord)
    +
    +data PartialAttribute = PartialAttribute AttributeDescription [AttributeValue]
    +    deriving (Show, Eq, Ord)
    +
    +newtype LdapDn = LdapDn LdapString
    +    deriving (Show, Eq, Ord)
    +
    +newtype RelativeLdapDn = RelativeLdapDn LdapString
    +    deriving (Show, Eq, Ord)
    +
    +newtype ReferralUris = ReferralUris (NonEmpty Uri)
    +    deriving (Show, Eq, Ord)
    +
    +newtype Uri = Uri LdapString
    +    deriving (Show, Eq, Ord)
    +
    +data Operation =
    +    Add
    +  | Delete
    +  | Replace
    +    deriving (Show, Eq, Ord)
    +
    +-- | The LDAPString is a notational convenience to indicate that, although
    +-- strings of LDAPString type encode as ASN.1 OCTET STRING types, the
    +-- [ISO10646] character set (a superset of [Unicode]) is used, encoded
    +-- following the UTF-8 [RFC3629] algorithm.
    +newtype LdapString = LdapString Text
    +    deriving (Show, Eq, Ord)
    +
    +newtype LdapOid = LdapOid ByteString
    +    deriving (Show, Eq, Ord)
    +
    + diff --git a/src/Ldap-Client-Add.html b/src/Ldap-Client-Add.html new file mode 100644 index 0000000..4337346 --- /dev/null +++ b/src/Ldap-Client-Add.html @@ -0,0 +1,55 @@ + + + + + +src/Ldap/Client/Add.hs + + + +
    module Ldap.Client.Add
    +  ( add
    +  , addEither
    +  , addAsync
    +  , addAsyncSTM
    +  ) where
    +
    +import           Control.Monad.STM (STM, atomically)
    +import           Data.List.NonEmpty (NonEmpty((:|)))
    +
    +import qualified Ldap.Asn1.Type as Type
    +import           Ldap.Client.Internal
    +
    +
    +add :: Ldap -> Dn -> AttrList NonEmpty -> IO ()
    +add l dn as =
    +  raise =<< addEither l dn as
    +
    +addEither :: Ldap -> Dn -> AttrList NonEmpty -> IO (Either ResponseError ())
    +addEither l dn as =
    +  wait =<< addAsync l dn as
    +
    +addAsync :: Ldap -> Dn -> AttrList NonEmpty -> IO (Async ())
    +addAsync l dn as =
    +  atomically (addAsyncSTM l dn as)
    +
    +addAsyncSTM :: Ldap -> Dn -> AttrList NonEmpty -> STM (Async ())
    +addAsyncSTM l dn as =
    +  let req = addRequest dn as in sendRequest l (addResult req) req
    +
    +addRequest :: Dn -> AttrList NonEmpty -> Request
    +addRequest (Dn dn) as =
    +  Type.AddRequest (Type.LdapDn (Type.LdapString dn))
    +                  (Type.AttributeList (map f as))
    + where
    +  f (Attr x, xs) = Type.Attribute (Type.AttributeDescription (Type.LdapString x))
    +                                  (fmap Type.AttributeValue xs)
    +
    +addResult :: Request -> Response -> Either ResponseError ()
    +addResult req (Type.AddResponse (Type.LdapResult code (Type.LdapDn (Type.LdapString dn))
    +                                                      (Type.LdapString msg) _) :| [])
    +  | Type.Success <- code = Right ()
    +  | otherwise = Left (ResponseErrorCode req code (Dn dn) msg)
    +addResult req res = Left (ResponseInvalid req res)
    +
    + diff --git a/src/Ldap-Client-Bind.html b/src/Ldap-Client-Bind.html new file mode 100644 index 0000000..af963cd --- /dev/null +++ b/src/Ldap-Client-Bind.html @@ -0,0 +1,77 @@ + + + + + +src/Ldap/Client/Bind.hs + + + +
    module Ldap.Client.Bind
    +  ( bind
    +  , bindEither
    +  , bindAsync
    +  , bindAsyncSTM
    +  , unbindAsync
    +  , unbindAsyncSTM
    +  ) where
    +
    +import           Control.Monad (void)
    +import           Control.Monad.STM (STM, atomically)
    +import           Data.List.NonEmpty (NonEmpty((:|)))
    +
    +import qualified Ldap.Asn1.Type as Type
    +import           Ldap.Client.Internal
    +
    +
    +bind :: Ldap -> Dn -> Password -> IO ()
    +bind l username password =
    +  raise =<< bindEither l username password
    +
    +bindEither :: Ldap -> Dn -> Password -> IO (Either ResponseError ())
    +bindEither l username password =
    +  wait =<< bindAsync l username password
    +
    +bindAsync :: Ldap -> Dn -> Password -> IO (Async ())
    +bindAsync l username password =
    +  atomically (bindAsyncSTM l username password)
    +
    +bindAsyncSTM :: Ldap -> Dn -> Password -> STM (Async ())
    +bindAsyncSTM l username password =
    +  let req = bindRequest username password in sendRequest l (bindResult req) req
    +
    +bindRequest :: Dn -> Password -> Request
    +bindRequest (Dn username) (Password password) =
    +  Type.BindRequest ldapVersion
    +                   (Type.LdapDn (Type.LdapString username))
    +                   (Type.Simple password)
    + where
    +  ldapVersion = 3
    +
    +bindResult :: Request -> Response -> Either ResponseError ()
    +bindResult req (Type.BindResponse (Type.LdapResult code (Type.LdapDn (Type.LdapString dn))
    +                                                        (Type.LdapString msg) _) _ :| [])
    +  | Type.Success <- code = Right ()
    +  | otherwise = Left (ResponseErrorCode req code (Dn dn) msg)
    +bindResult req res = Left (ResponseInvalid req res)
    +
    +
    +-- | Note that 'unbindAsync' does not return an 'Async',
    +-- because LDAP server never responds to @UnbindRequest@s, hence
    +-- a call to 'wait' on a hypothetical 'Async' would have resulted
    +-- in an exception anyway.
    +unbindAsync :: Ldap -> IO ()
    +unbindAsync =
    +  atomically . unbindAsyncSTM
    +
    +-- | Note that 'unbindAsyncSTM' does not return an 'Async',
    +-- because LDAP server never responds to @UnbindRequest@s, hence
    +-- a call to 'wait' on a hypothetical 'Async' would have resulted
    +-- in an exception anyway.
    +unbindAsyncSTM :: Ldap -> STM ()
    +unbindAsyncSTM l =
    +  void (sendRequest l die Type.UnbindRequest)
    + where
    +  die = error "Ldap.Client: do not wait for the response to UnbindRequest"
    +
    + diff --git a/src/Ldap-Client-Compare.html b/src/Ldap-Client-Compare.html new file mode 100644 index 0000000..a883caf --- /dev/null +++ b/src/Ldap-Client-Compare.html @@ -0,0 +1,57 @@ + + + + + +src/Ldap/Client/Compare.hs + + + +
    module Ldap.Client.Compare
    +  ( compare
    +  , compareEither
    +  , compareAsync
    +  , compareAsyncSTM
    +  ) where
    +
    +import           Control.Monad.STM (STM, atomically)
    +import           Data.ByteString (ByteString)
    +import           Data.List.NonEmpty (NonEmpty((:|)))
    +import           Prelude hiding (compare)
    +
    +import           Ldap.Client.Internal
    +import qualified Ldap.Asn1.Type as Type
    +
    +
    +compare :: Ldap -> Dn -> Attr -> ByteString -> IO Bool
    +compare l dn k v =
    +  raise =<< compareEither l dn k v
    +
    +compareEither :: Ldap -> Dn -> Attr -> ByteString -> IO (Either ResponseError Bool)
    +compareEither l dn k v =
    +  wait =<< compareAsync l dn k v
    +
    +compareAsync :: Ldap -> Dn -> Attr -> ByteString -> IO (Async Bool)
    +compareAsync l dn k v =
    +  atomically (compareAsyncSTM l dn k v)
    +
    +compareAsyncSTM :: Ldap -> Dn -> Attr -> ByteString -> STM (Async Bool)
    +compareAsyncSTM l dn k v =
    +  let req = compareRequest dn k v in sendRequest l (compareResult req) req
    +
    +compareRequest :: Dn -> Attr -> ByteString -> Request
    +compareRequest (Dn dn) (Attr k) v =
    +  Type.CompareRequest (Type.LdapDn (Type.LdapString dn))
    +                      (Type.AttributeValueAssertion
    +                        (Type.AttributeDescription (Type.LdapString k))
    +                        (Type.AssertionValue v))
    +
    +compareResult :: Request -> Response -> Either ResponseError Bool
    +compareResult req (Type.CompareResponse (Type.LdapResult code (Type.LdapDn (Type.LdapString dn))
    +                                                              (Type.LdapString msg) _) :| [])
    +  | Type.CompareTrue  <- code = Right True
    +  | Type.CompareFalse <- code = Right False
    +  | otherwise = Left (ResponseErrorCode req code (Dn dn) msg)
    +compareResult req res = Left (ResponseInvalid req res)
    +
    + diff --git a/src/Ldap-Client-Delete.html b/src/Ldap-Client-Delete.html new file mode 100644 index 0000000..c10197e --- /dev/null +++ b/src/Ldap-Client-Delete.html @@ -0,0 +1,51 @@ + + + + + +src/Ldap/Client/Delete.hs + + + +
    module Ldap.Client.Delete
    +  ( delete
    +  , deleteEither
    +  , deleteAsync
    +  , deleteAsyncSTM
    +  ) where
    +
    +import           Control.Concurrent.STM (STM, atomically)
    +import           Data.List.NonEmpty (NonEmpty((:|)))
    +
    +import qualified Ldap.Asn1.Type as Type
    +import           Ldap.Client.Internal
    +
    +
    +delete :: Ldap -> Dn -> IO ()
    +delete l dn =
    +  raise =<< deleteEither l dn
    +
    +deleteEither :: Ldap -> Dn -> IO (Either ResponseError ())
    +deleteEither l dn =
    +  wait =<< deleteAsync l dn
    +
    +deleteAsync :: Ldap -> Dn -> IO (Async ())
    +deleteAsync l dn =
    +  atomically (deleteAsyncSTM l dn)
    +
    +deleteAsyncSTM :: Ldap -> Dn -> STM (Async ())
    +deleteAsyncSTM l dn =
    +  let req = deleteRequest dn in sendRequest l (deleteResult req) req
    +
    +deleteRequest :: Dn -> Request
    +deleteRequest (Dn dn) =
    +  Type.DeleteRequest (Type.LdapDn (Type.LdapString dn))
    +
    +deleteResult :: Request -> Response -> Either ResponseError ()
    +deleteResult req (Type.DeleteResponse (Type.LdapResult code (Type.LdapDn (Type.LdapString dn))
    +                                                            (Type.LdapString msg) _) :| [])
    +  | Type.Success <- code = Right ()
    +  | otherwise = Left (ResponseErrorCode req code (Dn dn) msg)
    +deleteResult req res = Left (ResponseInvalid req res)
    +
    + diff --git a/src/Ldap-Client-Extended.html b/src/Ldap-Client-Extended.html new file mode 100644 index 0000000..ca12d31 --- /dev/null +++ b/src/Ldap-Client-Extended.html @@ -0,0 +1,75 @@ + + + + + +src/Ldap/Client/Extended.hs + + + +
    {-# LANGUAGE OverloadedStrings #-}
    +module Ldap.Client.Extended
    +  ( extended
    +  , extendedEither
    +  , extendedAsync
    +  , extendedAsyncSTM
    +  , startTls
    +  , startTlsEither
    +  , startTlsAsync
    +  , startTlsAsyncSTM
    +  ) where
    +
    +import           Control.Monad ((<=<))
    +import           Control.Monad.STM (STM, atomically)
    +import           Data.ByteString (ByteString)
    +import           Data.List.NonEmpty (NonEmpty((:|)))
    +
    +import qualified Ldap.Asn1.Type as Type
    +import           Ldap.Client.Internal
    +
    +
    +extended :: Ldap -> Oid -> Maybe ByteString -> IO ()
    +extended l oid mv =
    +  raise =<< extendedEither l oid mv
    +
    +extendedEither :: Ldap -> Oid -> Maybe ByteString -> IO (Either ResponseError ())
    +extendedEither l oid mv =
    +  wait =<< extendedAsync l oid mv
    +
    +extendedAsync :: Ldap -> Oid -> Maybe ByteString -> IO (Async ())
    +extendedAsync l oid mv =
    +  atomically (extendedAsyncSTM l oid mv)
    +
    +extendedAsyncSTM :: Ldap -> Oid -> Maybe ByteString -> STM (Async ())
    +extendedAsyncSTM l oid mv =
    +  let req = extendedRequest oid mv in sendRequest l (extendedResult req) req
    +
    +extendedRequest :: Oid -> Maybe ByteString -> Request
    +extendedRequest (Oid oid) =
    +  Type.ExtendedRequest (Type.LdapOid oid)
    +
    +extendedResult :: Request -> Response -> Either ResponseError ()
    +extendedResult req (Type.ExtendedResponse (Type.LdapResult code (Type.LdapDn (Type.LdapString dn))
    +                                                                (Type.LdapString msg) _) _ _ :| [])
    +  | Type.Success <- code = Right ()
    +  | otherwise = Left (ResponseErrorCode req code (Dn dn) msg)
    +extendedResult req res = Left (ResponseInvalid req res)
    +
    +
    +startTls :: Ldap -> IO ()
    +startTls =
    +  raise <=< startTlsEither
    +
    +startTlsEither :: Ldap -> IO (Either ResponseError ())
    +startTlsEither =
    +  wait <=< startTlsAsync
    +
    +startTlsAsync :: Ldap -> IO (Async ())
    +startTlsAsync =
    +  atomically . startTlsAsyncSTM
    +
    +startTlsAsyncSTM :: Ldap -> STM (Async ())
    +startTlsAsyncSTM l =
    +  extendedAsyncSTM l (Oid "1.3.6.1.4.1.1466.20037") Nothing
    +
    + diff --git a/src/Ldap-Client-Internal.html b/src/Ldap-Client-Internal.html new file mode 100644 index 0000000..733dde5 --- /dev/null +++ b/src/Ldap-Client-Internal.html @@ -0,0 +1,123 @@ + + + + + +src/Ldap/Client/Internal.hs + + + +
    {-# LANGUAGE DeriveDataTypeable #-}
    +{-# LANGUAGE NamedFieldPuns #-}
    +module Ldap.Client.Internal
    +  ( Host(..)
    +  , PortNumber
    +  , Ldap(..)
    +  , ClientMessage(..)
    +  , Type.ResultCode(..)
    +  , Async
    +  , Oid(..)
    +  , AttrList
    +    -- * Waiting for Request Completion
    +  , wait
    +  , waitSTM
    +    -- * Misc
    +  , Response
    +  , ResponseError(..)
    +  , Request
    +  , raise
    +  , sendRequest
    +  , Dn(..)
    +  , RelativeDn(..)
    +  , Password(..)
    +  , Attr(..)
    +  , unAttr
    +  ) where
    +
    +import           Control.Concurrent.STM (STM, atomically)
    +import           Control.Concurrent.STM.TMVar (TMVar, newEmptyTMVar, readTMVar)
    +import           Control.Concurrent.STM.TQueue (TQueue, writeTQueue)
    +import           Control.Exception (Exception, throwIO)
    +import           Data.ByteString (ByteString)
    +import           Data.List.NonEmpty (NonEmpty)
    +import           Data.Text (Text)
    +import           Data.Typeable (Typeable)
    +import           Network (PortNumber)
    +
    +import qualified Ldap.Asn1.Type as Type
    +
    +
    +data Host =
    +    Plain String
    +  | Secure String
    +  | Insecure String
    +    deriving (Show, Eq, Ord)
    +
    +data Ldap = Ldap
    +  { client  :: TQueue ClientMessage
    +  } deriving (Eq)
    +
    +data ClientMessage = New Request (TMVar (NonEmpty Type.ProtocolServerOp))
    +type Request = Type.ProtocolClientOp
    +type InMessage = Type.ProtocolServerOp
    +type Response = NonEmpty InMessage
    +
    +data Async a = Async (STM (Either ResponseError a))
    +
    +instance Functor Async where
    +  fmap f (Async stm) = Async (fmap (fmap f) stm)
    +
    +
    +newtype Dn = Dn Text
    +    deriving (Show, Eq)
    +
    +newtype RelativeDn = RelativeDn Text
    +    deriving (Show, Eq)
    +
    +newtype Oid = Oid ByteString
    +    deriving (Show, Eq)
    +
    +newtype Password = Password ByteString
    +    deriving (Show, Eq)
    +
    +
    +data ResponseError =
    +    ResponseInvalid Request Response
    +  | ResponseErrorCode Request Type.ResultCode Dn Text
    +    deriving (Show, Eq, Typeable)
    +
    +instance Exception ResponseError
    +
    +
    +
    +newtype Attr = Attr Text
    +    deriving (Show, Eq)
    +
    +type AttrList f = [(Attr, f ByteString)]
    +
    +-- 'Attr' unwrapper. This is a separate function not to turn 'Attr''s
    +-- 'Show' instance into complete and utter shit.
    +unAttr :: Attr -> Text
    +unAttr (Attr a) = a
    +
    +
    +wait :: Async a -> IO (Either ResponseError a)
    +wait = atomically . waitSTM
    +
    +waitSTM :: Async a -> STM (Either ResponseError a)
    +waitSTM (Async stm) = stm
    +
    +
    +sendRequest :: Ldap -> (Response -> Either ResponseError a) -> Request -> STM (Async a)
    +sendRequest l p msg =
    +  do var <- newEmptyTMVar
    +     writeRequest l var msg
    +     return (Async (fmap p (readTMVar var)))
    +
    +writeRequest :: Ldap -> TMVar Response -> Request -> STM ()
    +writeRequest Ldap { client } var msg = writeTQueue client (New msg var)
    +
    +raise :: Exception e => Either e a -> IO a
    +raise = either throwIO return
    +
    + diff --git a/src/Ldap-Client-Modify.html b/src/Ldap-Client-Modify.html new file mode 100644 index 0000000..9c4e286 --- /dev/null +++ b/src/Ldap-Client-Modify.html @@ -0,0 +1,102 @@ + + + + + +src/Ldap/Client/Modify.hs + + + +
    module Ldap.Client.Modify
    +  ( Operation(..)
    +  , modify
    +  , modifyEither
    +  , modifyAsync
    +  , modifyAsyncSTM
    +  , modifyDn
    +  , modifyDnEither
    +  , modifyDnAsync
    +  , modifyDnAsyncSTM
    +  ) where
    +
    +import           Control.Monad.STM (STM, atomically)
    +import           Data.ByteString (ByteString)
    +import           Data.List.NonEmpty (NonEmpty((:|)))
    +
    +import qualified Ldap.Asn1.Type as Type
    +import           Ldap.Client.Internal
    +
    +
    +data Operation =
    +    Delete Attr [ByteString]
    +  | Add Attr [ByteString]
    +  | Replace Attr [ByteString]
    +    deriving (Show, Eq)
    +
    +modify :: Ldap -> Dn -> [Operation] -> IO ()
    +modify l dn as =
    +  raise =<< modifyEither l dn as
    +
    +modifyEither :: Ldap -> Dn -> [Operation] -> IO (Either ResponseError ())
    +modifyEither l dn as =
    +  wait =<< modifyAsync l dn as
    +
    +modifyAsync :: Ldap -> Dn -> [Operation] -> IO (Async ())
    +modifyAsync l dn as =
    +  atomically (modifyAsyncSTM l dn as)
    +
    +modifyAsyncSTM :: Ldap -> Dn -> [Operation] -> STM (Async ())
    +modifyAsyncSTM l dn xs =
    +  let req = modifyRequest dn xs in sendRequest l (modifyResult req) req
    +
    +modifyRequest :: Dn -> [Operation] -> Request
    +modifyRequest (Dn dn) xs =
    +  Type.ModifyRequest (Type.LdapDn (Type.LdapString dn)) (map f xs)
    + where
    +  f (Delete (Attr k) vs) =
    +    (Type.Delete, Type.PartialAttribute (Type.AttributeDescription (Type.LdapString k))
    +                                        (map Type.AttributeValue vs))
    +  f (Add (Attr k) vs) =
    +    (Type.Add, Type.PartialAttribute (Type.AttributeDescription (Type.LdapString k))
    +                                     (map Type.AttributeValue vs))
    +  f (Replace (Attr k) vs) =
    +    (Type.Replace, Type.PartialAttribute (Type.AttributeDescription (Type.LdapString k))
    +                                         (map Type.AttributeValue vs))
    +
    +modifyResult :: Request -> Response -> Either ResponseError ()
    +modifyResult req (Type.ModifyResponse (Type.LdapResult code (Type.LdapDn (Type.LdapString dn)) (Type.LdapString msg) _) :| [])
    +  | Type.Success <- code = Right ()
    +  | otherwise = Left (ResponseErrorCode req code (Dn dn) msg)
    +modifyResult req res = Left (ResponseInvalid req res)
    +
    +
    +modifyDn :: Ldap -> Dn -> RelativeDn -> Bool -> Maybe Dn -> IO ()
    +modifyDn l dn rdn del new =
    +  raise =<< modifyDnEither l dn rdn del new
    +
    +modifyDnEither :: Ldap -> Dn -> RelativeDn -> Bool -> Maybe Dn -> IO (Either ResponseError ())
    +modifyDnEither l dn rdn del new =
    +  wait =<< modifyDnAsync l dn rdn del new
    +
    +modifyDnAsync :: Ldap -> Dn -> RelativeDn -> Bool -> Maybe Dn -> IO (Async ())
    +modifyDnAsync l dn rdn del new =
    +  atomically (modifyDnAsyncSTM l dn rdn del new)
    +
    +modifyDnAsyncSTM :: Ldap -> Dn -> RelativeDn -> Bool -> Maybe Dn -> STM (Async ())
    +modifyDnAsyncSTM l dn rdn del new =
    +  let req = modifyDnRequest dn rdn del new in sendRequest l (modifyDnResult req) req
    +
    +modifyDnRequest :: Dn -> RelativeDn -> Bool -> Maybe Dn -> Request
    +modifyDnRequest (Dn dn) (RelativeDn rdn) del new =
    +  Type.ModifyDnRequest (Type.LdapDn (Type.LdapString dn))
    +                       (Type.RelativeLdapDn (Type.LdapString rdn))
    +                       del
    +                       (fmap (\(Dn dn') -> Type.LdapDn (Type.LdapString dn')) new)
    +
    +modifyDnResult :: Request -> Response -> Either ResponseError ()
    +modifyDnResult req (Type.ModifyDnResponse (Type.LdapResult code (Type.LdapDn (Type.LdapString dn)) (Type.LdapString msg) _) :| [])
    +  | Type.Success <- code = Right ()
    +  | otherwise = Left (ResponseErrorCode req code (Dn dn) msg)
    +modifyDnResult req res = Left (ResponseInvalid req res)
    +
    + diff --git a/src/Ldap-Client-Search.html b/src/Ldap-Client-Search.html new file mode 100644 index 0000000..adced5e --- /dev/null +++ b/src/Ldap-Client-Search.html @@ -0,0 +1,189 @@ + + + + + +src/Ldap/Client/Search.hs + + + +
    {-# LANGUAGE CPP #-}
    +{-# LANGUAGE NamedFieldPuns #-}
    +module Ldap.Client.Search
    +  ( search
    +  , searchEither
    +  , searchAsync
    +  , searchAsyncSTM
    +  , Search
    +  , Mod
    +  , Type.Scope(..)
    +  , scope
    +  , size
    +  , time
    +  , typesOnly
    +  , derefAliases
    +  , Filter(..)
    +  , SearchEntry(..)
    +  ) where
    +
    +import           Control.Monad.STM (STM, atomically)
    +import           Data.ByteString (ByteString)
    +import           Data.Int (Int32)
    +import           Data.List.NonEmpty (NonEmpty((:|)))
    +import qualified Data.List.NonEmpty as NonEmpty
    +import           Data.Maybe (mapMaybe)
    +#if __GLASGOW_HASKELL__ >= 710
    +import           Data.Semigroup (Semigroup(..))
    +#else
    +import           Data.Semigroup (Semigroup(..), Monoid(..))
    +#endif
    +
    +import qualified Ldap.Asn1.Type as Type
    +import           Ldap.Client.Internal
    +
    +
    +search :: Ldap -> Dn -> Mod Search -> Filter -> [Attr] -> IO [SearchEntry]
    +search l base opts flt attributes =
    +  raise =<< searchEither l base opts flt attributes
    +
    +searchEither
    +  :: Ldap
    +  -> Dn
    +  -> Mod Search
    +  -> Filter
    +  -> [Attr]
    +  -> IO (Either ResponseError [SearchEntry])
    +searchEither l base opts flt attributes =
    +  wait =<< searchAsync l base opts flt attributes
    +
    +searchAsync :: Ldap -> Dn -> Mod Search -> Filter -> [Attr] -> IO (Async [SearchEntry])
    +searchAsync l base opts flt attributes =
    +  atomically (searchAsyncSTM l base opts flt attributes)
    +
    +searchAsyncSTM :: Ldap -> Dn -> Mod Search -> Filter -> [Attr] -> STM (Async [SearchEntry])
    +searchAsyncSTM l base opts flt attributes =
    +  let req = searchRequest base opts flt attributes in sendRequest l (searchResult req) req
    +
    +searchRequest :: Dn -> Mod Search -> Filter -> [Attr] -> Request
    +searchRequest (Dn base) (Mod m) flt attributes =
    +  Type.SearchRequest (Type.LdapDn (Type.LdapString base))
    +                     _scope
    +                     _derefAliases
    +                     _size
    +                     _time
    +                     _typesOnly
    +                     (fromFilter flt)
    +                     (Type.AttributeSelection (map (Type.LdapString . unAttr) attributes))
    + where
    +  Search { _scope, _derefAliases, _size, _time, _typesOnly } =
    +    m defaultSearch
    +  fromFilter (Not x) = Type.Not (fromFilter x)
    +  fromFilter (And xs) = Type.And (fmap fromFilter xs)
    +  fromFilter (Or xs) = Type.Or (fmap fromFilter xs)
    +  fromFilter (Present (Attr x)) =
    +    Type.Present (Type.AttributeDescription (Type.LdapString x))
    +  fromFilter (Attr x := y) =
    +    Type.EqualityMatch
    +      (Type.AttributeValueAssertion (Type.AttributeDescription (Type.LdapString x))
    +                                    (Type.AssertionValue y))
    +  fromFilter (Attr x :>= y) =
    +    Type.GreaterOrEqual
    +      (Type.AttributeValueAssertion (Type.AttributeDescription (Type.LdapString x))
    +                                    (Type.AssertionValue y))
    +  fromFilter (Attr x :<= y) =
    +    Type.LessOrEqual
    +      (Type.AttributeValueAssertion (Type.AttributeDescription (Type.LdapString x))
    +                                    (Type.AssertionValue y))
    +  fromFilter (Attr x :~= y) =
    +    Type.ApproxMatch
    +      (Type.AttributeValueAssertion (Type.AttributeDescription (Type.LdapString x))
    +                                    (Type.AssertionValue y))
    +  fromFilter (Attr x :=* (mi, xs, mf)) =
    +    Type.Substrings
    +      (Type.SubstringFilter (Type.AttributeDescription (Type.LdapString x))
    +                            (NonEmpty.fromList (concat
    +                              [ maybe [] (\i -> [Type.Initial (Type.AssertionValue i)]) mi
    +                              , fmap (Type.Any . Type.AssertionValue) xs
    +                              , maybe [] (\f -> [Type.Final (Type.AssertionValue f)]) mf
    +                              ])))
    +  fromFilter ((mx, mr, b) ::= y) =
    +    Type.ExtensibleMatch
    +      (Type.MatchingRuleAssertion (fmap (\(Attr r) -> Type.MatchingRuleId (Type.LdapString r)) mr)
    +                                  (fmap (\(Attr x) -> Type.AttributeDescription (Type.LdapString x)) mx)
    +                                  (Type.AssertionValue y)
    +                                  b)
    +
    +searchResult :: Request -> Response -> Either ResponseError [SearchEntry]
    +searchResult req (Type.SearchResultDone (Type.LdapResult code (Type.LdapDn (Type.LdapString dn'))
    +                                                              (Type.LdapString msg) _) :| xs)
    +  | Type.Success <- code = Right (mapMaybe g xs)
    +  | Type.AdminLimitExceeded <- code = Right (mapMaybe g xs)
    +  | Type.SizeLimitExceeded <- code = Right (mapMaybe g xs)
    +  | otherwise = Left (ResponseErrorCode req code (Dn dn') msg)
    + where
    +  g (Type.SearchResultEntry (Type.LdapDn (Type.LdapString dn))
    +                            (Type.PartialAttributeList ys)) =
    +    Just (SearchEntry (Dn dn) (map h ys))
    +  g _ = Nothing
    +  h (Type.PartialAttribute (Type.AttributeDescription (Type.LdapString x))
    +                           y) = (Attr x, fmap j y)
    +  j (Type.AttributeValue x) = x
    +searchResult req res = Left (ResponseInvalid req res)
    +
    +data Search = Search
    +  { _scope        :: Type.Scope
    +  , _derefAliases :: Type.DerefAliases
    +  , _size         :: Int32
    +  , _time         :: Int32
    +  , _typesOnly    :: Bool
    +  } deriving (Show, Eq)
    +
    +defaultSearch :: Search
    +defaultSearch = Search
    +  { _scope        = Type.BaseObject
    +  , _size         = 0
    +  , _time         = 0
    +  , _typesOnly    = False
    +  , _derefAliases = Type.NeverDerefAliases
    +  }
    +
    +scope :: Type.Scope -> Mod Search
    +scope x = Mod (\y -> y { _scope = x })
    +
    +size :: Int32 -> Mod Search
    +size x = Mod (\y -> y { _size = x })
    +
    +time :: Int32 -> Mod Search
    +time x = Mod (\y -> y { _time = x })
    +
    +typesOnly :: Bool -> Mod Search
    +typesOnly x = Mod (\y -> y { _typesOnly = x })
    +
    +derefAliases :: Type.DerefAliases -> Mod Search
    +derefAliases x = Mod (\y -> y { _derefAliases = x })
    +
    +newtype Mod a = Mod (a -> a)
    +
    +instance Semigroup (Mod a) where
    +  Mod f <> Mod g = Mod (g . f)
    +
    +instance Monoid (Mod a) where
    +  mempty = Mod id
    +  mappend = (<>)
    +
    +data Filter =
    +    Not Filter
    +  | And (NonEmpty Filter)
    +  | Or (NonEmpty Filter)
    +  | Present Attr
    +  | Attr := ByteString
    +  | Attr :>= ByteString
    +  | Attr :<= ByteString
    +  | Attr :~= ByteString
    +  | Attr :=* (Maybe ByteString, [ByteString], Maybe ByteString)
    +  | (Maybe Attr, Maybe Attr, Bool) ::= ByteString
    +
    +data SearchEntry = SearchEntry Dn (AttrList [])
    +    deriving (Show, Eq)
    +
    + diff --git a/src/Ldap-Client.html b/src/Ldap-Client.html new file mode 100644 index 0000000..af6edfb --- /dev/null +++ b/src/Ldap-Client.html @@ -0,0 +1,216 @@ + + + + + +src/Ldap/Client.hs + + + +
    {-# LANGUAGE CPP #-}
    +{-# LANGUAGE BangPatterns #-}
    +{-# LANGUAGE NamedFieldPuns #-}
    +module Ldap.Client
    +  ( Host(..)
    +  , Ldap
    +  , LdapError(..)
    +  , ResponseError(..)
    +  , Type.ResultCode(..)
    +  , Async
    +  , with
    +    -- * Bind
    +  , bind
    +    -- * Search
    +  , search
    +  , SearchEntry(..)
    +    -- ** Search modifiers
    +  , Search
    +  , Mod
    +  , scope
    +  , Type.Scope(..)
    +  , size
    +  , time
    +  , typesOnly
    +  , derefAliases
    +  , Filter(..)
    +    -- * Modify
    +  , modify
    +  , Operation(..)
    +    -- * Add
    +  , add
    +    -- * Delete
    +  , delete
    +    -- * ModifyDn
    +  , modifyDn
    +    -- * Compare
    +  , compare
    +    -- * Extended
    +  , extended
    +    -- * Waiting for completion
    +  , wait
    +    -- * Miscellanous
    +  , Dn(..)
    +  , RelativeDn(..)
    +  , Oid(..)
    +  , Password(..)
    +  , AttrList
    +  , Attr(..)
    +    -- * Re-exports
    +  , NonEmpty
    +  , PortNumber
    +  ) where
    +
    +#if __GLASGOW_HASKELL__ < 710
    +import           Control.Applicative ((<$>))
    +#endif
    +import qualified Control.Concurrent.Async as Async
    +import           Control.Concurrent.STM (atomically)
    +import           Control.Concurrent.STM.TMVar (putTMVar)
    +import           Control.Concurrent.STM.TQueue (TQueue, newTQueueIO, writeTQueue, readTQueue)
    +import           Control.Exception (Handler(..), bracket, throwIO, catches)
    +import           Control.Monad (forever)
    +import qualified Data.ASN1.BinaryEncoding as Asn1
    +import qualified Data.ASN1.Encoding as Asn1
    +import qualified Data.ASN1.Error as Asn1
    +import qualified Data.ByteString as ByteString
    +import qualified Data.ByteString.Lazy as ByteString.Lazy
    +import           Data.Foldable (traverse_, asum)
    +import           Data.Function (fix)
    +import           Data.List.NonEmpty (NonEmpty((:|)))
    +import qualified Data.Map.Strict as Map
    +import           Data.Monoid (Endo(appEndo))
    +import           Network.Connection (Connection)
    +import qualified Network.Connection as Conn
    +import qualified System.IO.Error as IO
    +import           Prelude hiding (compare)
    +
    +import           Ldap.Asn1.ToAsn1 (ToAsn1(toAsn1))
    +import           Ldap.Asn1.FromAsn1 (FromAsn1, parseAsn1)
    +import qualified Ldap.Asn1.Type as Type
    +import           Ldap.Client.Internal
    +import           Ldap.Client.Bind (bind, unbindAsync)
    +import           Ldap.Client.Search
    +  ( search
    +  , Search
    +  , Mod
    +  , scope
    +  , size
    +  , time
    +  , typesOnly
    +  , derefAliases
    +  , Filter(..)
    +  , SearchEntry(..)
    +  )
    +import           Ldap.Client.Modify (Operation(..), modify, modifyDn)
    +import           Ldap.Client.Add (add)
    +import           Ldap.Client.Delete (delete)
    +import           Ldap.Client.Compare (compare)
    +import           Ldap.Client.Extended (extended)
    +
    +
    +newLdap :: IO Ldap
    +newLdap = Ldap
    +  <$> newTQueueIO
    +
    +data LdapError =
    +    IOError IOError
    +  | ParseError Asn1.ASN1Error
    +  | ResponseError ResponseError
    +    deriving (Show, Eq)
    +
    +-- | The entrypoint into LDAP.
    +with :: Host -> PortNumber -> (Ldap -> IO a) -> IO (Either LdapError a)
    +with host port f = do
    +  context <- Conn.initConnectionContext
    +  bracket (Conn.connectTo context params) Conn.connectionClose (\conn ->
    +    bracket newLdap unbindAsync (\l -> do
    +      inq  <- newTQueueIO
    +      outq <- newTQueueIO
    +      Async.withAsync (input inq conn) $ \i ->
    +        Async.withAsync (output outq conn) $ \o ->
    +          Async.withAsync (dispatch l inq outq) $ \d ->
    +            Async.withAsync (f l) $ \u ->
    +              fmap (Right . snd) (Async.waitAnyCancel [i, o, d, u])))
    + `catches`
    +  [ Handler (return . Left . IOError)
    +  , Handler (return . Left . ParseError)
    +  , Handler (return . Left . ResponseError)
    +  ]
    + where
    +  params = Conn.ConnectionParams
    +    { Conn.connectionHostname =
    +        case host of
    +          Plain    h -> h
    +          Secure   h -> h
    +          Insecure h -> h
    +    , Conn.connectionPort = port
    +    , Conn.connectionUseSecure =
    +        case host of
    +          Plain  _ -> Nothing
    +          Secure _ -> Just Conn.TLSSettingsSimple
    +            { Conn.settingDisableCertificateValidation = False
    +            , Conn.settingDisableSession = False
    +            , Conn.settingUseServerName = False
    +            }
    +          Insecure _ -> Just Conn.TLSSettingsSimple
    +            { Conn.settingDisableCertificateValidation = True
    +            , Conn.settingDisableSession = False
    +            , Conn.settingUseServerName = False
    +            }
    +    , Conn.connectionUseSocks = Nothing
    +    }
    +
    +input :: FromAsn1 a => TQueue a -> Connection -> IO b
    +input inq conn = flip fix [] $ \loop chunks -> do
    +  chunk <- Conn.connectionGet conn 8192
    +  case ByteString.length chunk of
    +    0 -> throwIO (IO.mkIOError IO.eofErrorType "Ldap.Client.input" Nothing Nothing)
    +    _ -> do
    +      let chunks' = chunk : chunks
    +      case Asn1.decodeASN1 Asn1.DER (ByteString.Lazy.fromChunks (reverse chunks')) of
    +        Left  Asn1.ParsingPartial
    +                   -> loop chunks'
    +        Left  e    -> throwIO e
    +        Right asn1 -> do
    +          flip fix asn1 $ \loop' asn1' ->
    +            case parseAsn1 asn1' of
    +              Nothing -> return ()
    +              Just (asn1'', a) -> do
    +                atomically (writeTQueue inq a)
    +                loop' asn1''
    +          loop []
    +
    +output :: ToAsn1 a => TQueue a -> Connection -> IO b
    +output out conn = forever $ do
    +  msg <- atomically (readTQueue out)
    +  Conn.connectionPut conn (encode (toAsn1 msg))
    + where
    +  encode x = Asn1.encodeASN1' Asn1.DER (appEndo x [])
    +
    +dispatch
    +  :: Ldap
    +  -> TQueue (Type.LdapMessage Type.ProtocolServerOp)
    +  -> TQueue (Type.LdapMessage Request)
    +  -> IO a
    +dispatch Ldap { client } inq outq =
    +  flip fix (Map.empty, Map.empty, 1) $ \loop (!got, !results, !counter) ->
    +    loop =<< atomically (asum
    +      [ do New new var <- readTQueue client
    +           writeTQueue outq (Type.LdapMessage (Type.Id counter) new Nothing)
    +           return (got, Map.insert (Type.Id counter) var results, counter + 1)
    +      , do Type.LdapMessage mid op _ <- readTQueue inq
    +           case op of
    +             Type.SearchResultEntry {} ->
    +               return (Map.insertWith (++) mid [op] got, results, counter)
    +             Type.SearchResultReference {} ->
    +               return (got, results, counter)
    +             Type.SearchResultDone {} -> do
    +               let stack = Map.findWithDefault [] mid got
    +               traverse_ (\var -> putTMVar var (op :| stack)) (Map.lookup mid results)
    +               return (Map.delete mid got, Map.delete mid results, counter)
    +             _ -> do
    +               traverse_ (\var -> putTMVar var (op :| [])) (Map.lookup mid results)
    +               return (Map.delete mid got, Map.delete mid results, counter)
    +      ])
    +
    + diff --git a/src/hscolour.css b/src/hscolour.css new file mode 100644 index 0000000..c15919e --- /dev/null +++ b/src/hscolour.css @@ -0,0 +1,5 @@ +.hs-keyglyph, .hs-layout {color: red;} +.hs-keyword {color: blue;} +.hs-comment, .hs-comment a {color: green;} +.hs-str, .hs-chr {color: teal;} +.hs-keyword, .hs-conid, .hs-varid, .hs-conop, .hs-varop, .hs-num, .hs-cpp, .hs-sel, .hs-definition {} diff --git a/synopsis.png b/synopsis.png new file mode 100644 index 0000000000000000000000000000000000000000..85fb86ec84907bcc86531dc82871948ff4d471fa GIT binary patch literal 11327 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 B5rhB$ literal 0 HcmV?d00001