module Ldap.Asn1.Type where import Data.ByteString (ByteString) import Data.Int (Int8, Int32) import Data.List.NonEmpty (NonEmpty) import Data.Text (Text) -- | Message envelope. (Section 4.1.1.) data LdapMessage op = LdapMessage { ldapMessageId :: !Id , ldapMessageOp :: !op , ldapMessageControls :: !(Maybe Controls) } deriving (Show, Eq) -- | Every message being processed has a unique non-zero integer ID. (Section 4.1.1.1.) newtype Id = Id { unId :: Int32 } deriving (Show, Eq, Ord) -- | Client requests. The RFC doesn't make a difference between 'ProtocolClientOp' -- and 'ProtocolServerOp' but it's useful to distinguish between them in Haskell. 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) -- | Server responses. The RFC doesn't make a difference between 'ProtocolClientOp' -- and 'ProtocolServerOp' but it's useful to distinguish between them in Haskell. 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) | IntermediateResponse !(Maybe LdapOid) !(Maybe ByteString) deriving (Show, Eq) -- | Not really a choice until SASL is supported. data AuthenticationChoice = Simple !ByteString | Sasl !SaslMechanism !(Maybe Text) deriving (Show, Eq) -- | SASL Mechanism, for now only SASL EXTERNAL is supported data SaslMechanism = External deriving (Show, Eq) -- | Scope of the search to be performed. data Scope = BaseObject -- ^ Constrained to the entry named by baseObject. | SingleLevel -- ^ Constrained to the immediate subordinates of the entry named by baseObject. | WholeSubtree -- ^ Constrained to the entry named by baseObject and to all its subordinates. deriving (Show, Eq) -- | An indicator as to whether or not alias entries (as defined in -- [RFC4512]) are to be dereferenced during stages of the Search -- operation. data DerefAliases = NeverDerefAliases -- ^ Do not dereference aliases in searching or in locating the base object of the Search. | DerefInSearching -- ^ While searching subordinates of the base object, dereference any alias within the search scope. | DerefFindingBaseObject -- ^ Dereference aliases in locating the base object of the Search. | DerefAlways -- ^ Dereference aliases both in searching and in locating the base object of the Search. deriving (Show, Eq) -- | Conditions that must be fulfilled in order for the Search to match a given entry. data Filter = And !(NonEmpty Filter) -- ^ All filters evaluate to @TRUE@ | Or !(NonEmpty Filter) -- ^ Any filter evaluates to @TRUE@ | Not !Filter -- ^ Filter evaluates to @FALSE@ | EqualityMatch !AttributeValueAssertion -- ^ @EQUALITY@ rule returns @TRUE@ | Substrings !SubstringFilter -- ^ @SUBSTR@ rule returns @TRUE@ | GreaterOrEqual !AttributeValueAssertion -- ^ @ORDERING@ rule returns @FALSE@ | LessOrEqual !AttributeValueAssertion -- ^ @ORDERING@ or @EQUALITY@ rule returns @TRUE@ | Present !AttributeDescription -- ^ Attribute is present in the entry | ApproxMatch !AttributeValueAssertion -- ^ Same as 'EqualityMatch' for most servers | ExtensibleMatch !MatchingRuleAssertion deriving (Show, Eq) data SubstringFilter = SubstringFilter !AttributeDescription !(NonEmpty Substring) deriving (Show, Eq) data Substring = Initial !AssertionValue | Any !AssertionValue | Final !AssertionValue deriving (Show, Eq) data MatchingRuleAssertion = MatchingRuleAssertion !(Maybe MatchingRuleId) !(Maybe AttributeDescription) !AssertionValue !Bool deriving (Show, Eq) -- | Matching rules are defined in Section 4.1.3 of [RFC4512]. A matching -- rule is identified in the protocol by the printable representation of -- either its or one of its short name descriptors -- [RFC4512], e.g., 'caseIgnoreMatch' or '2.5.13.2'. (Section 4.1.8.) newtype MatchingRuleId = MatchingRuleId LdapString deriving (Show, Eq) newtype AttributeSelection = AttributeSelection [LdapString] deriving (Show, Eq) newtype AttributeList = AttributeList [Attribute] deriving (Show, Eq) newtype PartialAttributeList = PartialAttributeList [PartialAttribute] deriving (Show, Eq) newtype Controls = Controls [Control] deriving (Show, Eq) data Control = Control !LdapOid !Bool !(Maybe ByteString) deriving (Show, Eq) data LdapResult = LdapResult !ResultCode !LdapDn !LdapString !(Maybe ReferralUris) deriving (Show, Eq) -- | LDAP operation's result. 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) newtype AttributeDescription = AttributeDescription LdapString deriving (Show, Eq) newtype AttributeValue = AttributeValue ByteString deriving (Show, Eq) data AttributeValueAssertion = AttributeValueAssertion !AttributeDescription !AssertionValue deriving (Show, Eq) newtype AssertionValue = AssertionValue ByteString deriving (Show, Eq) data Attribute = Attribute !AttributeDescription !(NonEmpty AttributeValue) deriving (Show, Eq) data PartialAttribute = PartialAttribute !AttributeDescription ![AttributeValue] deriving (Show, Eq) -- | An LDAPDN is defined to be the representation of a Distinguished Name -- (DN) after encoding according to the specification in [RFC4514]. newtype LdapDn = LdapDn LdapString deriving (Show, Eq) -- | A RelativeLDAPDN is defined to be the representation of a Relative -- Distinguished Name (RDN) after encoding according to the -- specification in [RFC4514]. newtype RelativeLdapDn = RelativeLdapDn LdapString deriving (Show, Eq) newtype ReferralUris = ReferralUris (NonEmpty Uri) deriving (Show, Eq) newtype Uri = Uri LdapString deriving (Show, Eq) data Operation = Add | Delete | Replace deriving (Show, Eq) -- | 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. (Section 4.1.2.) newtype LdapString = LdapString Text deriving (Show, Eq) -- | The LDAPOID is a notational convenience to indicate that the -- permitted value of this string is a (UTF-8 encoded) dotted-decimal -- representation of an OBJECT IDENTIFIER. Although an LDAPOID is -- encoded as an OCTET STRING, values are limited to the definition of -- \ given in Section 1.4 of [RFC4512]. newtype LdapOid = LdapOid Text deriving (Show, Eq)