Completed
Push — master ( e53fe2...bb559d )
by Jörg
02:04
created

Domrobot::deleteRecord()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 8
rs 9.4285
cc 1
eloc 5
nc 1
nop 2
1
<?php
2
/**
3
     * Created by PhpStorm.
4
     * User: joerg
5
     * Date: 14.02.16
6
     * Time: 20:31
7
     * copied and modified from https://github.com/inwx/php-client
8
     */
9
namespace Bingemer\InwxBundle\Classes;
10
11
/**
12
 * Class Domrobot
13
 * @package Bingemer\InwxBundle\Classes
14
 */
15
class Domrobot
16
{
17
    private $debug = false;
18
    private $address;
19
    private $language;
20
    private $customer = "";
21
    private $clTRID = null;
22
23
    private $_ver = "2.4";
24
    private $_cachedir;
25
    private $_cookiefile = NULL;
26
    private $loginResult = NULL;
27
28
    /**
29
     * Domrobot constructor.
30
     * @param $address
31
     * @param string $locale
32
     * @param $cache_dir
33
     * @param $username
34
     * @param $password
35
     * @param null $sharedSecret
36
     */
37
    public function __construct($address, $locale = 'en', $cache_dir, $username, $password, $sharedSecret = null)
38
    {
39
        $this->address = (substr($address, -1) != "/") ? $address . "/" : $address;
40
        $this->_cachedir = $cache_dir;
41
        $this->_cookiefile = tempnam($this->_cachedir, 'INWX');
42
        $this->setLanguage($locale);
43
        $this->loginResult = $this->login($username, $password, $sharedSecret);
44
    }
45
46
    /**
47
     * @param string $name
48
     * @param $ip
49
     * @param string $domain
50
     * @param string $type
51
     * @return mixed|string
52
     */
53
    public function createRecord($name, $ip, $domain = 'somedomainnameyouwishtoupgrade.de', $type = 'A')
54
    {
55
        if (strpos($name, $domain) === false) {
56
            $name = $name . "." . $domain;
57
        }
58
        try {
59
            $result = $this->call('nameserver', 'createRecord', array(
60
                'domain' => $domain,
61
                'type' => $type,
62
                'name' => $name,
63
                'content' => $ip
64
            ));
65
            return $result;
66
        } catch (\Exception $e) {
67
            return $e->getMessage();
68
        }
69
    }
70
71
    /**
72
     * @param integer $id
73
     * @param $ip
74
     * @return mixed
75
     */
76
    public function updateRecord($id, $ip)
77
    {
78
        $result = $this->call('nameserver', 'updateRecord', array(
79
            'id' => $id,
80
            'content' => $ip
81
        ));
82
        return $result;
83
    }
84
85
    /**
86
     * @param integer $id
87
     * @param bool $testing
88
     * @return mixed
89
     */
90
    public function deleteRecord($id, $testing = false)
91
    {
92
        $result = $this->call('nameserver', 'deleteRecord', array(
93
            'id' => $id,
94
            'testing' => $testing
95
        ));
96
        return $result;
97
    }
98
99
    /**
100
     * @param $username
101
     * @param $password
102
     * @param null $sharedSecret
103
     * @return mixed
104
     */
105
    public function login($username, $password, $sharedSecret = null)
106
    {
107
        $fp = fopen($this->_cookiefile, "w");
108
        fclose($fp);
109
110
        $params = array();
111
        if (!empty($this->language)) {
112
            $params['lang'] = $this->language;
113
        } else {
114
            $params['lang'] = "en"; //fallback
115
        }
116
        $params['user'] = $username;
117
        $params['pass'] = $password;
118
119
        $loginRes = $this->call('account', 'login', $params);
120
        if (!empty($sharedSecret) && $loginRes['code'] == 1000 && !empty($loginRes['resData']['tfa'])) {
121
            $_tan = $this->_getSecretCode($sharedSecret);
122
            $unlockRes = $this->call('account', 'unlock', array('tan' => $_tan));
123
            if ($unlockRes['code'] == 1000) {
124
                return $loginRes;
125
            } else {
126
                return $unlockRes;
127
            }
128
        } else {
129
            return $loginRes;
130
        }
131
    }
132
133
    /**
134
     * @param string $object
135
     * @param string $method
136
     * @param array $params
137
     * @return mixed
138
     */
139
    public function call($object, $method, array $params = array())
0 ignored issues
show
Coding Style introduced by
call uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
140
    {
141
        if (isset($this->customer) && $this->customer != "") {
142
            $params['subuser'] = $this->customer;
143
        }
144
        if (!empty($this->clTRID)) {
145
            $params['clTRID'] = $this->clTRID;
146
        }
147
148
        $request = xmlrpc_encode_request(strtolower($object . "." . $method), $params, array("encoding" => "UTF-8", "escaping" => "markup", "verbosity" => "no_white_space"));
149
        $header = array();
150
        $header[] = "Content-Type: text/xml";
151
        $header[] = "Connection: keep-alive";
152
        $header[] = "Keep-Alive: 300";
153
        $header[] = "X-FORWARDED-FOR: " . @$_SERVER['HTTP_X_FORWARDED_FOR'];
154
        $ch = curl_init();
155
        curl_setopt($ch, CURLOPT_URL, $this->address);
156
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
157
        curl_setopt($ch, CURLOPT_TIMEOUT, 65);
158
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
159
        curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
160
        curl_setopt($ch, CURLOPT_COOKIEFILE, $this->_cookiefile);
161
        curl_setopt($ch, CURLOPT_COOKIEJAR, $this->_cookiefile);
162
        curl_setopt($ch, CURLOPT_POST, true);
163
        curl_setopt($ch, CURLOPT_POSTFIELDS, $request);
164
        curl_setopt($ch, CURLOPT_USERAGENT, "DomRobot/{$this->_ver} (PHP " . phpversion() . ")");
165
        $response = curl_exec($ch);
166
        curl_close($ch);
167
        if ($this->debug) {
168
            echo "Request:\n" . $request . "\n";
169
            echo "Response:\n" . $response . "\n";
170
        }
171
        return xmlrpc_decode($response, 'UTF-8');
172
    }
173
174
    /**
175
     * @param $secret
176
     * @return string
177
     */
178
    private function _getSecretCode($secret)
179
    {
180
        $_timeSlice = floor(time() / 30);
181
        $_codeLength = 6;
182
183
        $secretKey = $this->_base32Decode($secret);
184
        // Pack time into binary string
185
        $time = chr(0) . chr(0) . chr(0) . chr(0) . pack('N*', $_timeSlice);
186
        // Hash it with users secret key
187
        $hm = hash_hmac('SHA1', $time, $secretKey, true);
188
        // Use last nipple of result as index/offset
189
        $offset = ord(substr($hm, -1)) & 0x0F;
190
        // grab 4 bytes of the result
191
        $hashPart = substr($hm, $offset, 4);
192
193
        // Unpak binary value
194
        $value = unpack('N', $hashPart);
195
        $value = $value[1];
196
        // Only 32 bits
197
        $value = $value & 0x7FFFFFFF;
198
199
        $modulo = pow(10, $_codeLength);
200
        return str_pad($value % $modulo, $_codeLength, '0', STR_PAD_LEFT);
201
    }
202
203
    /**
204
     * @param $secret
205
     * @return string|false
206
     */
207
    private function _base32Decode($secret)
208
    {
209
        if (empty($secret)) {
210
            return '';
211
        }
212
213
        $base32chars = $this->_getBase32LookupTable();
214
        $base32charsFlipped = array_flip($base32chars);
215
216
        $paddingCharCount = substr_count($secret, $base32chars[32]);
217
        $allowedValues = array(6, 4, 3, 1, 0);
218
        if (!in_array($paddingCharCount, $allowedValues)) {
219
            return false;
220
        }
221
        for ($i = 0; $i < 4; $i++) {
222
            if ($paddingCharCount == $allowedValues[$i] &&
223
                substr($secret, -($allowedValues[$i])) != str_repeat($base32chars[32], $allowedValues[$i])
224
            ) {
225
                return false;
226
            }
227
        }
228
        $secret = str_replace('=', '', $secret);
229
        $secret = str_split($secret);
230
        $secretCount = count($secret);
231
        $binaryString = "";
232
        for ($i = 0; $i < $secretCount; $i = $i + 8) {
233
            $x = "";
234
            if (!in_array($secret[$i], $base32chars)) {
235
                return false;
236
            }
237
            for ($j = 0; $j < 8; $j++) {
238
                $x .= str_pad(base_convert(@$base32charsFlipped[@$secret[$i + $j]], 10, 2), 5, '0', STR_PAD_LEFT);
239
            }
240
            $eightBits = str_split($x, 8);
241
            $eightBitsCount = count($eightBits);
242
            for ($z = 0; $z < $eightBitsCount; $z++) {
243
                $binaryString .= (($y = chr(base_convert($eightBits[$z], 2, 10))) || ord($y) == 48) ? $y : "";
244
            }
245
        }
246
        return $binaryString;
247
    }
248
249
    /**
250
     * @return string[]
251
     */
252
    private function _getBase32LookupTable()
253
    {
254
        return array(
255
            'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', // 7
256
            'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', // 15
257
            'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', // 23
258
            'Y', 'Z', '2', '3', '4', '5', '6', '7', // 31
259
            '=' // padding char
260
        );
261
    }
262
263
    /**
264
     *  logout on destruct
265
     */
266
    public function __destruct()
267
    {
268
        $this->logout();
269
    }
270
271
    /**
272
     * @return mixed
273
     */
274
    public function logout()
275
    {
276
        $ret = $this->call('account', 'logout');
277
        if (file_exists($this->_cookiefile)) {
278
            unlink($this->_cookiefile);
279
        }
280
        return $ret;
281
    }
282
283
    /**
284
     * @return string
285
     */
286
    public function getLanguage()
287
    {
288
        return $this->language;
289
    }
290
291
    /**
292
     * @param string $language
293
     */
294
    public function setLanguage($language)
295
    {
296
        $this->language = $language;
297
    }
298
299
    /**
300
     * @return bool
301
     */
302
    public function getDebug()
303
    {
304
        return $this->debug;
305
    }
306
307
    /**
308
     * @param bool $debug
309
     */
310
    public function setDebug($debug = false)
311
    {
312
        $this->debug = (bool)$debug;
313
    }
314
315
    /**
316
     * @return string
317
     */
318
    public function getCookiefile()
319
    {
320
        return $this->_cookiefile;
321
    }
322
323
    /**
324
     * @param $file
325
     * @throws \Exception
326
     */
327
    public function setCookiefile($file)
328
    {
329
        if ((file_exists($file) && !is_writable($file)) || (!file_exists($file) && !is_writeable(dirname($file)))) {
330
            throw new \Exception("Cannot write cookiefile: '{$this->_cookiefile}'. Please check file/folder permissions.", 2400);
331
        }
332
        $this->_cookiefile = $file;
333
    }
334
335
    /**
336
     * @return string
337
     */
338
    public function getCustomer()
339
    {
340
        return $this->customer;
341
    }
342
343
    /**
344
     * @param $customer
345
     */
346
    public function setCustomer($customer)
347
    {
348
        $this->customer = (string)$customer;
349
    }
350
351
    /**
352
     * @return string
353
     */
354
    public function getClTrId()
355
    {
356
        return $this->clTRID;
357
    }
358
359
    /**
360
     * @param $clTrId
361
     */
362
    public function setClTrId($clTrId)
363
    {
364
        $this->clTRID = (string)$clTrId;
365
    }
366
}