Completed
Push — master ( f93b78...cabf1c )
by
unknown
01:28
created

AbstractClient::prepareConnectionOptions()   A

Complexity

Conditions 5
Paths 16

Size

Total Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 24
rs 9.2248
c 0
b 0
f 0
cc 5
nc 16
nop 1
1
<?php
2
3
namespace AfriCC\EPP;
4
5
use AfriCC\EPP\Frame\Command\Login as LoginCommand;
6
use AfriCC\EPP\Frame\Response as ResponseFrame;
7
use AfriCC\EPP\Frame\ResponseFactory;
8
use Exception;
9
10
/**
11
 * An abstract client client for the Extensible Provisioning Protocol (EPP)
12
 *
13
 * Extend this class in your custom EPP Client
14
 *
15
 * @see http://tools.ietf.org/html/rfc5734
16
 * @see ClientInterface
17
 *
18
 * As this class is abstract and relies on subclass implementation details it's untestable
19
 * @codeCoverageIgnore
20
 */
21
abstract class AbstractClient implements ClientInterface
22
{
23
    protected $host;
24
    protected $port;
25
    protected $username;
26
    protected $password;
27
    protected $services;
28
    protected $serviceExtensions;
29
    protected $ssl;
30
    protected $local_cert;
31
    protected $ca_cert;
32
    protected $pk_cert;
33
    protected $passphrase;
34
    protected $debug;
35
    protected $connect_timeout;
36
    protected $timeout;
37
    protected $objectSpec;
38
39
    /**
40
     * {@inheritdoc}
41
     *
42
     * @see \AfriCC\EPP\ClientInterface::connect()
43
     */
44
    abstract public function connect($newPassword = false);
45
46
    abstract public function close();
47
48
    abstract protected function log($message);
49
50
    /**
51
     * Send frame to EPP server
52
     *
53
     * @param FrameInterface $frame Frame to send
54
     *
55
     * @throws Exception on send error
56
     */
57
    abstract public function sendFrame(FrameInterface $frame);
58
59
    /**
60
     * Get response frame from EPP server (use after sendFrame)
61
     *
62
     * @throws Exception on frame receive error
63
     *
64
     * @return string raw XML of EPP Frame
65
     */
66
    abstract public function getFrame();
67
68
    public function request(FrameInterface $frame)
69
    {
70
        if ($frame instanceof TransactionAwareInterface) {
71
            $frame->setClientTransactionId(
72
                $this->generateClientTransactionId()
73
                );
74
        }
75
76
        $this->sendFrame($frame);
77
78
        $return = $this->getFrame();
79
80
        return ResponseFactory::build($return, $this->objectSpec);
81
    }
82
83
    public function __construct(array $config, ObjectSpec $objectSpec = null)
84
    {
85
        if (!empty($config['debug']) && is_bool($config['debug'])) {
86
            $this->debug = $config['debug'];
87
        } else {
88
            $this->debug = false;
89
        }
90
91
        if (is_null($objectSpec)) {
92
            $objectSpec = new ObjectSpec();
93
        }
94
95
        $this->objectSpec = $objectSpec;
96
97
        $this->prepareConnectionOptions($config);
98
        $this->prepareCredentials($config);
99
        $this->prepareSSLOptions($config);
100
        $this->prepareEPPServices($config);
101
    }
102
103
    /**
104
     * Get client's ObjectSpec
105
     *
106
     * @return ObjectSpec
107
     */
108
    public function getObjectSpec()
109
    {
110
        return $this->objectSpec;
111
    }
112
113
    /**
114
     * Set client's ObjectSpec
115
     *
116
     * @param ObjectSpec $newObjectSpec
117
     */
118
    public function setObjectSpec(ObjectSpec $newObjectSpec)
119
    {
120
        $this->objectSpec = $newObjectSpec;
121
    }
122
123
    protected function prepareConnectionOptions(array $config)
124
    {
125
        if (!empty($config['host'])) {
126
            $this->host = (string) $config['host'];
127
        }
128
129
        if (!empty($config['port'])) {
130
            $this->port = (int) $config['port'];
131
        } else {
132
            $this->port = false;
133
        }
134
135
        if (!empty($config['connect_timeout'])) {
136
            $this->connect_timeout = (int) $config['connect_timeout'];
137
        } else {
138
            $this->connect_timeout = 16;
139
        }
140
141
        if (!empty($config['timeout'])) {
142
            $this->timeout = (int) $config['timeout'];
143
        } else {
144
            $this->timeout = 32;
145
        }
146
    }
147
148
    protected function prepareCredentials(array $config)
149
    {
150
        if (!empty($config['username'])) {
151
            $this->username = (string) $config['username'];
152
        }
153
154
        if (!empty($config['password'])) {
155
            $this->password = (string) $config['password'];
156
        }
157
    }
158
159
    protected function prepareSSLOptions(array $config)
160
    {
161
        if ((!empty($config['ssl']) && is_bool($config['ssl']))) {
162
            $this->ssl = $config['ssl'];
163
        } else {
164
            $this->ssl = false;
165
        }
166
167
        if (!empty($config['local_cert'])) {
168
            $this->local_cert = (string) $config['local_cert'];
169
170
            if (!is_readable($this->local_cert)) {
171
                throw new \Exception(sprintf('unable to read local_cert: %s', $this->local_cert));
172
            }
173
        }
174
175
        if (!empty($config['ca_cert'])) {
176
            $this->ca_cert = (string) $config['ca_cert'];
177
178
            if (!is_readable($this->ca_cert)) {
179
                throw new \Exception(sprintf('unable to read ca_cert: %s', $this->ca_cert));
180
            }
181
        }
182
183
        if (!empty($config['pk_cert'])) {
184
            $this->pk_cert = (string) $config['pk_cert'];
185
186
            if (!is_readable($this->pk_cert)) {
187
                throw new \Exception(sprintf('unable to read pk_cert: %s', $this->pk_cert));
188
            }
189
        }
190
191
        if (!empty($config['passphrase'])) {
192
            $this->passphrase = (string) $config['passphrase'];
193
        }
194
    }
195
196
    protected function prepareEPPServices(array $config)
197
    {
198
        if (!empty($config['services']) && is_array($config['services'])) {
199
            $this->services = $config['services'];
200
201
            if (!empty($config['serviceExtensions']) && is_array($config['serviceExtensions'])) {
202
                $this->serviceExtensions = $config['serviceExtensions'];
203
            }
204
        }
205
    }
206
207
    protected function generateClientTransactionId()
208
    {
209
        return Random::id(64, $this->username);
210
    }
211
212
    /**
213
     * Generate and send login frame
214
     *
215
     * @param bool|string $newPassword New password to set on login, false if not changing password
216
     *
217
     * @throws \Exception On unsuccessful login
218
     *
219
     * @return \AfriCC\EPP\Frame\Response Login response
220
     */
221
    protected function login($newPassword = false)
222
    {
223
        // send login command
224
        $login = new LoginCommand($this->objectSpec);
225
        $login->setClientId($this->username);
226
        $login->setPassword($this->password);
227
        if ($newPassword) {
228
            $login->setNewPassword($newPassword);
229
        }
230
        $login->setVersion('1.0');
231
        $login->setLanguage('en');
232
233
        if (!empty($this->services) && is_array($this->services)) {
234
            foreach ($this->services as $urn) {
235
                $login->addService($urn);
236
            }
237
238
            if (!empty($this->serviceExtensions) && is_array($this->serviceExtensions)) {
239
                foreach ($this->serviceExtensions as $extension) {
240
                    $login->addServiceExtension($extension);
241
                }
242
            }
243
        }
244
245
        $response = $this->request($login);
246
        unset($login);
247
248
        // check if login was successful
249
        if (!($response instanceof ResponseFrame)) {
250
            throw new \Exception('there was a problem logging onto the EPP server');
251
        } elseif ($response->code() !== 1000) {
252
            throw new \Exception($response->message(), $response->code());
253
        }
254
255
        return $response;
256
    }
257
}
258