Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
85.45% covered (warning)
85.45%
47 / 55
16.67% covered (danger)
16.67%
1 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
SessionClient
85.45% covered (warning)
85.45%
47 / 55
16.67% covered (danger)
16.67%
1 / 6
29.24
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 login
66.67% covered (warning)
66.67%
4 / 6
0.00% covered (danger)
0.00%
0 / 1
3.33
 loginExtended
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 logout
75.00% covered (warning)
75.00%
3 / 4
0.00% covered (danger)
0.00%
0 / 1
2.06
 IDNConvert
86.36% covered (warning)
86.36%
19 / 22
0.00% covered (danger)
0.00%
0 / 1
9.21
 autoIDNConvert
95.24% covered (success)
95.24%
20 / 21
0.00% covered (danger)
0.00%
0 / 1
11
1<?php
2
3#declare(strict_types=1);
4
5/**
6 * CNIC\RRPproxy
7 * Copyright © CentralNic Group PLC
8 */
9
10namespace CNIC\RRPproxy;
11
12/**
13 * RRPproxy API Client
14 *
15 * @package CNIC\RRPproxy
16 */
17
18class SessionClient extends \CNIC\HEXONET\SessionClient
19{
20    public function __construct()
21    {
22        parent::__construct(implode(DIRECTORY_SEPARATOR, [__DIR__, "config.json"]));
23    }
24    /**
25     * Perform API login to start session-based communication
26     * @param string $otp optional one time password
27     * @return \CNIC\HEXONET\Response Response
28     */
29    public function login($otp = "")
30    {
31        $this->setOTP($otp);
32        $rr = $this->request([
33            "COMMAND" => "StartSession",
34            "persistent" => 1
35        ]);
36        if ($rr->isSuccess()) {
37            $col = $rr->getColumn("SESSIONID");
38            $this->setSession($col ? $col->getData()[0] : "");
39        }
40        return $rr;
41    }
42
43    /**
44     * Perform API login to start session-based communication.
45     * Use given specific command parameters.
46     * @param array $params given specific command parameters
47     * @param string $otp optional one time password
48     * @return \CNIC\HEXONET\Response Response
49     */
50    public function loginExtended($params, $otp = "")
51    {
52        // no further parameters supported, falling back to standard
53        return $this->login($otp);
54    }
55
56    /**
57     * Perform API logout to close API session in use
58     * @return \CNIC\HEXONET\Response Response
59     */
60    public function logout()
61    {
62        $rr = $this->request(["COMMAND" => "StopSession"]);
63        if ($rr->isSuccess()) {
64            $this->setSession();
65        }
66        return $rr;
67    }
68
69    /**
70     * Convert domain names to idn + punycode if necessary
71     * @param array $domains list of domain names (or tlds)
72     * @return array
73     */
74    public function IDNConvert($domains)
75    {
76        $results = [];
77        foreach ($domains as $idx => $d) {
78            $results[$idx] = [
79                "PUNYCODE" => $d,
80                "IDN" => $d
81            ];
82        }
83        if ($this->settings["needsIDNConvert"]) {
84            foreach ($domains as $idx => $domain) {
85                $nontransitional = (bool)preg_match("/\.(be|ca|de|fr|pm|re|swiss|tf|wf|yt)\.?$/i", $domain);
86                $tmp = idn_to_ascii(
87                    $domain,
88                    ($nontransitional) ?
89                        IDNA_NONTRANSITIONAL_TO_ASCII :
90                        IDNA_DEFAULT,
91                    INTL_IDNA_VARIANT_UTS46
92                );
93                if ($tmp === false) {
94                    continue;
95                }
96                if (preg_match("/xn--/", $tmp)) {
97                    $results[$idx]["PUNYCODE"] = $tmp;
98                }
99                $tmp = idn_to_utf8(
100                    $results[$idx]["PUNYCODE"],
101                    ($nontransitional) ?
102                        IDNA_NONTRANSITIONAL_TO_ASCII :
103                        IDNA_DEFAULT,
104                    INTL_IDNA_VARIANT_UTS46
105                );
106                if (!empty($tmp)) {
107                    $results[$idx]["IDN"] = $tmp;
108                }
109            }
110        }
111        return $results;
112    }
113
114    /**
115     * Auto convert API command parameters to punycode, if necessary.
116     * @param array $cmd API command
117     * @return array
118     */
119    protected function autoIDNConvert($cmd)
120    {
121        // only convert if configured for the registrar
122        // and ignore commands in string format (even deprecated)
123        if (
124            !$this->settings["needsIDNConvert"]
125            || !function_exists("idn_to_ascii")
126        ) {
127            return $cmd;
128        }
129
130        $asciipattern = "/^[a-zA-Z0-9\.-]+$/i";
131        $keypattern = "/^(NAMESERVER|NS|DNSZONE)([0-9]*)$/i";// DOMAIN params get auto-converted by API, RSRBE-7149 for NS coverage
132        $objclasspattern = "/^(DOMAIN(APPLICATION|BLOCKING)?|NAMESERVER|NS)$/i";
133        $toconvert = [];
134        $idxs = [];
135        foreach ($cmd as $key => $val) {
136            if (
137                (
138                    (bool)preg_match($keypattern, $key)
139                    || (
140                        $key === "OBJECTID"
141                        && isset($cmd["OBJECTCLASS"])
142                        && (bool)preg_match($objclasspattern, $cmd["OBJECTCLASS"])
143                    )
144                )
145                && !(bool)preg_match($asciipattern, $val)
146            ) {
147                $toconvert[] = $val;
148                $idxs[] = $key;
149            }
150        }
151        if (!empty($toconvert)) {
152            $results = $this->IDNConvert($toconvert);
153            foreach ($results as $idx => $row) {
154                $cmd[$idxs[$idx]] = $row["PUNYCODE"];
155            }
156        }
157        return $cmd;
158    }
159}