1<?php
2/**
3 * This file is part of the FreeDSx LDAP package.
4 *
5 * (c) Chad Sikorra <Chad.Sikorra@gmail.com>
6 *
7 * For the full copyright and license information, please view the LICENSE
8 * file that was distributed with this source code.
9 */
10
11namespace FreeDSx\Ldap\Operation\Response;
12
13use FreeDSx\Asn1\Asn1;
14use FreeDSx\Asn1\Type\AbstractType;
15use FreeDSx\Asn1\Type\SequenceType;
16use FreeDSx\Ldap\Operation\LdapResult;
17
18/**
19 * RFC 4511 Section 4.2.2
20 *
21 * BindResponse ::= [APPLICATION 1] SEQUENCE {
22 *     COMPONENTS OF LDAPResult,
23 *     serverSaslCreds    [7] OCTET STRING OPTIONAL }
24 *
25 * @author Chad Sikorra <Chad.Sikorra@gmail.com>
26 */
27class BindResponse extends LdapResult
28{
29    protected $tagNumber = 1;
30
31    /**
32     * @var null|string
33     */
34    protected $saslCreds;
35
36    /**
37     * @param LdapResult $result
38     * @param null|string $saslCreds
39     */
40    public function __construct(LdapResult $result, ?string $saslCreds = null)
41    {
42        $this->saslCreds = $saslCreds;
43        parent::__construct($result->getResultCode(), $result->getDn(), $result->getDiagnosticMessage(), ...$result->getReferrals());
44    }
45
46    /**
47     * @return null|string
48     */
49    public function getSaslCredentials(): ?string
50    {
51        return $this->saslCreds;
52    }
53
54    /**
55     * {@inheritdoc}
56     */
57    public function toAsn1(): AbstractType
58    {
59        /** @var SequenceType $response */
60        $response = parent::toAsn1();
61
62        if ($this->saslCreds !== null) {
63            $response->addChild(Asn1::context(7, Asn1::octetString($this->saslCreds)));
64        }
65
66        return $response;
67    }
68
69    /**
70     * {@inheritdoc}
71     */
72    public static function fromAsn1(AbstractType $type)
73    {
74        [$resultCode, $dn, $diag, $ref] = self::parseResultData($type);
75        $saslCreds = null;
76
77        /** @var SequenceType $type */
78        foreach ($type->getChildren() as $child) {
79            if ($child->getTagNumber() === 7 && $child->getTagClass() === AbstractType::TAG_CLASS_CONTEXT_SPECIFIC) {
80                $saslCreds = $child->getValue();
81                break;
82            }
83        }
84
85        return new self(new LdapResult($resultCode, $dn, $diag, ...$ref), $saslCreds);
86    }
87}
88