Completed
Pull Request — master (#82)
by
unknown
02:05
created

AbstractClient::setObjectSpec()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
nc 1
cc 1
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
     * @return void Doesn't return!
55
     * @throws Exception on send error
56
     */
57
    abstract protected function sendFrame(FrameInterface $frame);
58
59
    /**
60
     * Get response frame from EPP server (use after sendFrame)
61
     *
62
     * @return string raw XML of EPP Frame
63
     * @throws Exception on frame receive error
64
     */
65
    abstract protected function getFrame();
66
67
    public function request(FrameInterface $frame)
68
    {
69
        if ($frame instanceof TransactionAwareInterface) {
70
            $frame->setClientTransactionId(
71
                $this->generateClientTransactionId()
72
                );
73
        }
74
75
        $this->sendFrame($frame);
76
77
        $return = $this->getFrame();
78
79
        return ResponseFactory::build($return, $this->objectSpec);
80
    }
81
82
    public function __construct(array $config, ObjectSpec $objectSpec = null)
83
    {
84
        if (!empty($config['debug']) && is_bool($config['debug'])) {
85
            $this->debug = $config['debug'];
86
        } else {
87
            $this->debug = false;
88
        }
89
90
        if(is_null($objectSpec)){
91
            $objectSpec = new ObjectSpec();
92
        }
93
94
        $this->objectSpec = $objectSpec;
95
96
        $this->prepareConnectionOptions($config);
97
        $this->prepareCredentials($config);
98
        $this->prepareSSLOptions($config);
99
        $this->prepareEPPServices($config);
100
    }
101
102
    /**
103
     * Get client's ObjectSpec
104
     *
105
     * @return ObjectSpec
106
     */
107
    public function getObjectSpec()
108
    {
109
        return $this->objectSpec;
110
    }
111
112
    /**
113
     * Set client's ObjectSpec
114
     *
115
     * @param ObjectSpec $newObjectSpec
116
     */
117
    public function setObjectSpec(ObjectSpec $newObjectSpec)
118
    {
119
        $this->objectSpec = $newObjectSpec;
120
    }
121
122
    protected function prepareConnectionOptions(array $config)
123
    {
124
        if (!empty($config['host'])) {
125
            $this->host = (string) $config['host'];
126
        }
127
128
        if (!empty($config['port'])) {
129
            $this->port = (int) $config['port'];
130
        } else {
131
            $this->port = false;
132
        }
133
134
        if (!empty($config['connect_timeout'])) {
135
            $this->connect_timeout = (int) $config['connect_timeout'];
136
        } else {
137
            $this->connect_timeout = 16;
138
        }
139
140
        if (!empty($config['timeout'])) {
141
            $this->timeout = (int) $config['timeout'];
142
        } else {
143
            $this->timeout = 32;
144
        }
145
    }
146
147
    protected function prepareCredentials(array $config)
148
    {
149
        if (!empty($config['username'])) {
150
            $this->username = (string) $config['username'];
151
        }
152
153
        if (!empty($config['password'])) {
154
            $this->password = (string) $config['password'];
155
        }
156
    }
157
158
    protected function prepareSSLOptions(array $config)
159
    {
160
        if ((!empty($config['ssl']) && is_bool($config['ssl']))) {
161
            $this->ssl = $config['ssl'];
162
        } else {
163
            $this->ssl = false;
164
        }
165
166
        if (!empty($config['local_cert'])) {
167
            $this->local_cert = (string) $config['local_cert'];
168
169
            if (!is_readable($this->local_cert)) {
170
                throw new \Exception(sprintf('unable to read local_cert: %s', $this->local_cert));
171
            }
172
        }
173
174
        if (!empty($config['ca_cert'])) {
175
            $this->ca_cert = (string) $config['ca_cert'];
176
177
            if (!is_readable($this->ca_cert)) {
178
                throw new \Exception(sprintf('unable to read ca_cert: %s', $this->ca_cert));
179
            }
180
        }
181
182
        if (!empty($config['pk_cert'])) {
183
            $this->pk_cert = (string) $config['pk_cert'];
184
185
            if (!is_readable($this->pk_cert)) {
186
                throw new \Exception(sprintf('unable to read pk_cert: %s', $this->pk_cert));
187
            }
188
        }
189
190
        if (!empty($config['passphrase'])) {
191
            $this->passphrase = (string) $config['passphrase'];
192
        }
193
    }
194
195
    protected function prepareEPPServices(array $config)
196
    {
197
        if (!empty($config['services']) && is_array($config['services'])) {
198
            $this->services = $config['services'];
199
200
            if (!empty($config['serviceExtensions']) && is_array($config['serviceExtensions'])) {
201
                $this->serviceExtensions = $config['serviceExtensions'];
202
            }
203
        }
204
    }
205
206
    protected function generateClientTransactionId()
207
    {
208
        return Random::id(64, $this->username);
209
    }
210
211
    /**
212
     * Generate and send login frame
213
     *
214
     * @param bool|string $newPassword New password to set on login, false if not changing password
215
     *
216
     * @throws \Exception On unsuccessful login
217
     *
218
     * @return \AfriCC\EPP\Frame\Response Login response
219
     */
220
    protected function login($newPassword = false)
221
    {
222
        // send login command
223
        $login = new LoginCommand($this->objectSpec);
224
        $login->setClientId($this->username);
225
        $login->setPassword($this->password);
226
        if ($newPassword) {
227
            $login->setNewPassword($newPassword);
228
        }
229
        $login->setVersion('1.0');
230
        $login->setLanguage('en');
231
232
        if (!empty($this->services) && is_array($this->services)) {
233
            foreach ($this->services as $urn) {
234
                $login->addService($urn);
235
            }
236
237
            if (!empty($this->serviceExtensions) && is_array($this->serviceExtensions)) {
238
                foreach ($this->serviceExtensions as $extension) {
239
                    $login->addServiceExtension($extension);
240
                }
241
            }
242
        }
243
244
        $response = $this->request($login);
245
        unset($login);
246
247
        // check if login was successful
248
        if (!($response instanceof ResponseFrame)) {
249
            throw new \Exception('there was a problem logging onto the EPP server');
250
        } elseif ($response->code() !== 1000) {
251
            throw new \Exception($response->message(), $response->code());
252
        }
253
254
        return $response;
255
    }
256
}
257