Passed
Branch master (334f84)
by
unknown
03:14
created

authCheck::nameReset()   F

Complexity

Conditions 29
Paths 536

Size

Total Lines 140
Code Lines 97

Duplication

Lines 48
Ratio 34.29 %

Importance

Changes 0
Metric Value
cc 29
eloc 97
nc 536
nop 0
dl 48
loc 140
rs 2.6347
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * The MIT License (MIT)
4
 *
5
 * Copyright (c) 2016 Robert Sardinia
6
 *
7
 * Permission is hereby granted, free of charge, to any person obtaining a copy
8
 * of this software and associated documentation files (the "Software"), to deal
9
 * in the Software without restriction, including without limitation the rights
10
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
 * copies of the Software, and to permit persons to whom the Software is
12
 * furnished to do so, subject to the following conditions:
13
 *
14
 * The above copyright notice and this permission notice shall be included in all
15
 * copies or substantial portions of the Software.
16
 *
17
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
 * SOFTWARE.
24
 */
25
26
27
/**
28
 * Class fileAuthCheck
29
 * @property int nextCheck
30
 */
31
class authCheck
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
32
{
33
34
    /**
35
     * @var
36
     */
37
    private $config;
38
    private $db;
39
    private $dbUser;
40
    private $dbPass;
41
    private $dbName;
42
    private $guildID;
43
    private $corpTickers;
44
    private $authGroups;
45
    private $exempt;
46
    private $alertChannel;
47
    private $guild;
48
    private $nameEnforce;
49
    private $standingsBased;
50
    private $nameCheck;
51
    private $apiKey;
52
    private $discord;
53
    private $logger;
54
55
    /**
56
     * @param $config
57
     * @param $discord
58
     * @param $logger
59
     */
60
    public function init($config, $discord, $logger)
61
    {
62
        $this->config = $config;
63
        $this->discord = $discord;
64
        $this->logger = $logger;
65
        $this->db = $config['database']['host'];
66
        $this->dbUser = $config['database']['user'];
67
        $this->dbPass = $config['database']['pass'];
68
        $this->dbName = $config['database']['database'];
69
        $this->guildID = $config['bot']['guild'];
70
        $this->exempt = $config['plugins']['auth']['exempt'];
71
        $this->corpTickers = $config['plugins']['auth']['corpTickers'];
72
        $this->nameEnforce = $config['plugins']['auth']['nameEnforce'];
73
        $this->standingsBased = $config['plugins']['auth']['standings']['enabled'];
74
        $this->apiKey = $config['eve']['apiKeys'];
75
        $this->authGroups = $config['plugins']['auth']['authGroups'];
76
        $this->alertChannel = $config['plugins']['auth']['alertChannel'];
77
        $this->guild = $config['bot']['guild'];
78
        $this->nextCheck = 0;
79
80
        //Set name check to happen if corpTicker or nameEnforce is set
81
        if ($this->nameEnforce === 'true' || $this->corpTickers === 'true') {
82
            $this->nameCheck = 'true';
83
        }
84
85
        //check if cache has been set
86
        $permsChecked = getPermCache('permsLastChecked');
87
        $namesChecked = getPermCache('nextRename');
88
        if ($namesChecked === NULL) {
89
            setPermCache('nextRename', time());
90
        }
91
92
        //if not set set for now (30 minutes from now for role removal)
93
        if ($permsChecked === NULL) {
94
            setPermCache('permsLastChecked', time() - 1);
95
            setPermCache('authStateLastChecked', time() + 1);
96
        }
97
    }
98
99
    public function tick()
100
    {
101
        // What was the servers last reported state
102
        $lastStatus = getPermCache('serverState');
103
        if ($lastStatus === 'online') {
104
            $permsChecked = getPermCache('permsLastChecked');
105
            $stateChecked = getPermCache('authStateLastChecked');
106
            $namesChecked = getPermCache('nextRename');
107
            $standingsChecked = getPermCache('nextStandingsCheck');
108
109
            if ($permsChecked <= time()) {
110
                $this->logger->addInfo('AuthCheck: Checking for users who have left corp/alliance....');
111
                $this->checkPermissions();
112
                $this->logger->addInfo('AuthCheck: Corp/alliance check complete.');
113
            }
114
115
            if ($stateChecked <= time()) {
116
                $this->logger->addInfo('AuthCheck: Checking for users who have been wrongly given roles....');
117
                $this->checkAuthState();
118
                $this->logger->addInfo('AuthCheck: Role check complete.');
119
            }
120
121
            if ($this->nameCheck === 'true' && $namesChecked <= time()) {
122
                $this->logger->addInfo('AuthCheck: Resetting player names....');
123
                $this->nameReset();
124
                $this->logger->addInfo('AuthCheck: Names reset.');
125
            }
126
127
            if ($this->standingsBased === 'true' && $standingsChecked <= time()) {
128
                $this->logger->addInfo('AuthCheck: Updating Standings');
129
                $this->standingsUpdate();
130
                $this->logger->addInfo('AuthCheck: Standings Updated');
131
            }
132
        }
133
    }
134
135
    /**
136
     * @return null
137
     */
138
139
    //Remove members who have roles but never authed
140
    private function checkPermissions()
141
    {
142
        //Get guild object
143
        $guild = $this->discord->guilds->get('id', $this->guildID);
144
145
        //Establish connection to mysql
146
        $conn = new mysqli($this->db, $this->dbUser, $this->dbPass, $this->dbName);
147
148
        $sql = "SELECT characterID, discordID, eveName, role FROM authUsers WHERE active='yes'";
149
150
        $result = $conn->query($sql);
151
152
        //Set empty arrays
153
        $corpArray = array();
154
        $allianceArray = array();
155
156
        // If config is outdated
157 View Code Duplication
        if (null === $this->authGroups) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
158
            $msg = '**Auth Failure:** Please update the bots config to the latest version.';
159
            queueMessage($msg, $this->alertChannel, $this->guild);
160
            $nextCheck = time() + 10800;
161
            setPermCache('permsLastChecked', $nextCheck);
162
            return null;
163
        }
164
165
        //Set corp/ally id arrays
166
        foreach ($this->authGroups as $authGroup) {
167
            if ($authGroup['corpID'] !== 0) {
168
                $corpArray[] = (int) $authGroup['corpID'];
169
            }
170
            if ($authGroup['allianceID'] !== 0) {
171
                $allianceArray[] = (int) $authGroup['allianceID'];
172
            }
173
        }
174
175
        if ($result->num_rows >= 1) {
176
            while ($rows = $result->fetch_assoc()) {
177
				$charID = $rows['characterID'];
178
				$discordID = $rows['discordID'];
179
				$role = $rows['role'];
180
				$member = $guild->members->get('id', $discordID);
181
				$eveName = $rows['eveName'];
182
				//Check if member has roles
183
				if (null === @$member->roles) {
184
					continue;
185
				}
186
187
				//Auth things
188
				$character = characterDetails($charID);
189
				//if issue with esi, skip
190
				$timeout = 0;
191 View Code Duplication
				while (null === $character) { //try 10 times to pull characterDetails
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
192
					if ($timeout > 9) {
193
						continue;
194
					}
195
					else{
196
						$character = characterDetails($charID);
197
						$timeout++;
198
					}
199
				}
200
				$corporationID = $character['corporation_id'];
201
				$corporationDetails = corpDetails($corporationID);
202
				$timeout = 0;
203
				while (null === $corporationDetails) { //try 10 times to pull corporationDetails
204
					if ($timeout > 9) {
205
						continue;
206
					}
207
					else{
208
						$corporationDetails = corpDetails($corporationID);
209
						$timeout++;
210
					}
211
				}
212
				$allianceID = @$corporationDetails['alliance_id'];
213
				//check if user authed based on standings
214
				$standings = null;
215
				if ($role === 'blue' || 'neut' || 'red') {
216
					$allianceContacts = getContacts($allianceID);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $allianceContacts is correct as getContacts($allianceID) (which targets getContacts()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
217
					$corpContacts = getContacts($corporationID);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $corpContacts is correct as getContacts($corporationID) (which targets getContacts()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
218
					if ($role === 'blue' && ((int) $allianceContacts['standing'] === 5 || 10 || (int) $corpContacts['standing'] === 5 || 10)) {
219
						$standings = 1;
220
					}
221
					if ($role === 'red' && ((int) $allianceContacts['standing'] === -5 || -10 || (int) $corpContacts['standing'] === -5 || -10)) {
222
						$standings = 1;
223
					}
224
					if ($role === 'neut' && ((int) $allianceContacts['standing'] === 0 || (int) $corpContacts['standing'] === 0 || (@(int) $allianceContacts['standings'] === null || '' && @(int) $corpContacts['standings'] === null || ''))) {
225
						$standings = 1;
226
					}
227
				}
228
				if (!in_array((int) $allianceID, $allianceArray) && !in_array((int) $corporationID, $corpArray) && null === $standings) {
229
					// Deactivate user in database
230
					$sql = "UPDATE authUsers SET active='no' WHERE discordID='$discordID'";
231
					$this->logger->addInfo("AuthCheck: {$eveName} account has been deactivated as they are no longer in a correct corp/alliance.");
232
					$conn->query($sql);
233
					continue;
234
				}
235
236
				$nextCheck = time() + 10800;
237
				setPermCache('permsLastChecked', $nextCheck);
238
			}
239
        }
240
        $nextCheck = time() + 10800;
241
        setPermCache('permsLastChecked', $nextCheck);
242
        return null;
243
    }
244
245
    //Check user corp/alliance affiliation
246
247
248
    private function checkAuthState()
249
    {
250
251
        //Check if exempt roles are set
252
        if (null === $this->exempt) {
253
            $this->exempt = '0';
254
        }
255
256
        // If config is outdated
257 View Code Duplication
        if (null === $this->authGroups) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
258
            $msg = '**Auth Failure:** Please update the bots config to the latest version.';
259
            queueMessage($msg, $this->alertChannel, $this->guild);
260
            //queue up next check
261
            $nextCheck = time() + 1800;
262
            setPermCache('authStateLastChecked', $nextCheck);
263
            return null;
264
        }
265
266
        //Establish connection to mysql
267
        $conn = new mysqli($this->db, $this->dbUser, $this->dbPass, $this->dbName);
268
269
        //get bot ID so we don't remove out own roles
270
        $botID = $this->discord->id;
271
272
        //Get guild object
273
        $guild = $this->discord->guilds->get('id', $this->guildID);
274
275
        //Check to make sure guildID is set correctly
276
        if (null === $guild) {
277
            $this->logger->addError('Config Error: Ensure the guild entry in the config is the guildID (aka serverID) for the main server that the bot is in.');
278
            $nextCheck = time() + 7200;
279
            setPermCache('authLastChecked', $nextCheck);
280
            return null;
281
        }
282
283
        //create empty array to store names
284
        $removedRoles = array();
285
        $userCount = 0;
286
287
        //Perform check if roles were added without permission
288
        foreach ($guild->members as $member) {
289
            $id = $member->id;
290
            $username = $member->username;
291
            $roles = $member->roles;
292
293
            //Skip to next member if this user has no roles
294
            if (null === $roles) {
295
                continue;
296
            }
297
            $sql = "SELECT * FROM authUsers WHERE discordID='$id' AND active='yes'";
298
            $result = $conn->query($sql);
299
300
            //If they are NOT active in the db, check for roles to remove
301
            if ($result->num_rows === 0) {
302
                $userCount++;
303
                foreach ($roles as $role) {
304
                    if ($id !== $botID && !in_array($role->name, $this->exempt, true)) {
305
                        $member->removeRole($role);
306
                        $guild->members->save($member);
307
                        // Add users name to array
308
                        if (!in_array($username, $removedRoles)) {
309
                            $removedRoles[] = $username;
310
                        }
311
                    }
312
                }
313
            }
314
        }
315
        //Report removed users to log and channel
316
        $nameList = implode(', ', $removedRoles);
317
        if ($userCount > 0 && strlen($nameList) > 3 && null !== $nameList) {
318
            $msg = "Following users roles have been removed - {$nameList}";
319
            queueMessage($msg, $this->alertChannel, $this->guild);
320
            $this->logger->addInfo("AuthCheck: Roles removed from {$nameList}");
321
        }
322
        //queue up next check
323
        $nextCheck = time() + 1800;
324
        setPermCache('authStateLastChecked', $nextCheck);
325
        return null;
326
    }
327
328
    private function nameReset()
329
    {
330
        //Get guild object
331
        $guild = $this->discord->guilds->get('id', $this->guildID);
332
333
        //Get name queue status
334
        $x = (int) getPermCache('nameQueueState');
335
336
        //Establish connection to mysql
337
        $conn = new mysqli($this->db, $this->dbUser, $this->dbPass, $this->dbName);
338
        $sql = "SELECT id FROM authUsers WHERE active='yes'";
339
        $count = $conn->query($sql);
340
        $rowAmount = round($count->num_rows / 2);
341
        if ($x === 1) {
342
            $sql = "SELECT characterID, discordID, eveName  FROM authUsers WHERE active='yes' ORDER BY id ASC LIMIT {$rowAmount} OFFSET {$rowAmount}";
343
            setPermCache('nameQueueState', 0);
344
        } else {
345
            $sql = "SELECT characterID, discordID, eveName  FROM authUsers WHERE active='yes' ORDER BY id ASC LIMIT {$rowAmount}";
346
            setPermCache('nameQueueState', 1);
347
        }
348
        $result = $conn->query($sql);
349
350
        // If config is outdated
351 View Code Duplication
        if (null === $this->authGroups) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
352
            $msg = '**Auth Failure:** Please update the bots config to the latest version.';
353
            queueMessage($msg, $this->alertChannel, $this->guild);
354
            $nextCheck = time() + 1800;
355
            setPermCache('nextRename', $nextCheck);
356
            return null;
357
        }
358
359
        if (@$result->num_rows >= 1) {
360
            while ($rows = $result->fetch_assoc()) {
361
                $charID = $rows['characterID'];
362
                $discordID = $rows['discordID'];
363
                $member = $guild->members->get('id', $discordID);
364
                $eveName = $rows['eveName'];
365
                //Check if member has roles
366
                if (null === @$member->roles) {
367
                    continue;
368
                }
369
370
                //Get current nickname
371
                $guild = $this->discord->guilds->get('id', $this->guildID);
372
                $member = $guild->members->get('id', $discordID);
373
                $nickName = $member->nick;
374
                $userName = $member->user->username;
375
                //If nick isn't set than make it username
376
                if ($nickName === '' || null === $nickName) {
377
                    $nickName = $userName;
378
                }
379
380
                //Check for bad tickers
381
                if (strpos($nickName, '[U]') !== false) {
382
                    $nickName = str_replace('[U]', '', $nickName);
383
                    queueRename($discordID, $nickName, $this->guildID);
384
                    continue;
385
                }
386
387
                //corp ticker
388
                if ($this->corpTickers === 'true') {
389
					$timeout = 0;
390
					$character = characterDetails($charID);
391 View Code Duplication
					while (null === $character) { //try 10 times to pull characterDetails
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
392
						if ($timeout > 9) {
393
							continue;
394
						}
395
						else{
396
							$character = characterDetails($charID);
397
							$timeout++;
398
						}
399
					}
400
                    if (!array_key_exists('corporation_id', $character)) {
401
                        continue;
402
                    }
403
                    $corpInfo = getCorpInfo($character['corporation_id']);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $corpInfo is correct as getCorpInfo($character['corporation_id']) (which targets getCorpInfo()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
404
                    //Clean bad entries
405
                    if (@$corpInfo['corpTicker'] === 'U') {
406
                        deleteCorpInfo(@$corpInfo['corpID']);
407
                    }
408
                    $nick = null;
409 View Code Duplication
                    if (null !== @$corpInfo['corpTicker']) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
410
                        $corpTicker = (string) $corpInfo['corpTicker'];
411
                        if ($this->nameEnforce === 'true') {
412
                            $nick = "[{$corpTicker}] {$eveName}";
413
                        } elseif ((string) $nickName === "[{$corpTicker}]") {
414
                            $nick = "[{$corpTicker}] {$userName}";
415
                        } elseif (strpos($nickName, $corpTicker) === false) {
416
                            $nick = "[{$corpTicker}] {$nickName}";
417
                        } elseif (strpos($nickName, $corpTicker) !== false) {
418
                            continue;
419
                        }
420
                        if ($nick !== $nickName) {
421
                            queueRename($discordID, $nick, $this->guildID);
422
                        }
423
                        continue;
424
                    }
425
                    $corporationDetails = corpDetails($character['corporation_id']);
426
                    if (null === $corporationDetails) {
427
                        continue;
428
                    }
429
                    $corpTicker = $corporationDetails['ticker'];
430
                    //Check for bad tickers (ESI ERROR?)
431
                    if (@$corpTicker === 'U') {
432
                        continue;
433
                    }
434
                    $corpName = (string) $corporationDetails['corporation_name'];
435 View Code Duplication
                    if (null !== $corpTicker) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
436
                        if ($this->nameEnforce === 'true') {
437
                            $nick = "[{$corpTicker}] {$eveName}";
438
                        } elseif ((string) $nickName === "[{$corpTicker}]") {
439
                            $nick = "[{$corpTicker}] {$userName}";
440
                        } elseif (strpos($nickName, $corpTicker) === false) {
441
                            $nick = "[{$corpTicker}] {$nickName}";
442
                        } elseif (strpos($nickName, $corpTicker) !== false) {
443
                            continue;
444
                        }
445
                        if ($nick !== $nickName) {
446
                            queueRename($discordID, $nick, $this->guildID);
447
                            addCorpInfo($character['corporation_id'], $corpTicker, $corpName);
448
                        }
449
                        continue;
450
                    }
451
                    continue;
452
                }
453
                $nick = "{$eveName}";
454
                if ($nick !== $nickName) {
455
                    queueRename($discordID, $nick, $this->guildID);
456
                }
457
                continue;
458
            }
459
            $nextCheck = time() + 1800;
460
            setPermCache('nextRename', $nextCheck);
461
            return null;
462
        }
463
        $nextCheck = time() + 1800;
464
        setPermCache('nextRename', $nextCheck);
465
        return null;
466
467
    }
468
469
    private function standingsUpdate()
470
    {
471
        foreach ($this->apiKey as $apiKey) {
472
            if ((string) $apiKey['keyID'] === (string) $this->config['plugins']['auth']['standings']['apiKey']) {
473
                $url = "https://api.eveonline.com/char/ContactList.xml.aspx?keyID={$apiKey['keyID']}&vCode={$apiKey['vCode']}&characterID={$apiKey['characterID']}";
474
                $xml = makeApiRequest($url);
475
                if (empty($xml)) {
476
                    return null;
477
                }
478
                foreach ($xml->result->rowset as $contactType) {
479
                    if ((string) $contactType->attributes()->name === 'corporateContactList' || 'allianceContactList') {
480
                        foreach ($contactType->row as $contact) {
481
                            if (null !== $contact['contactID'] && $contact['contactName'] && $contact['standing']) {
482
                                addContactInfo($contact['contactID'], $contact['contactName'], $contact['standing']);
483
                            }
484
                        }
485
                    }
486
                }
487
            }
488
        }
489
        $nextCheck = time() + 86400;
490
        setPermCache('nextStandingsCheck', $nextCheck);
491
    }
492
}
493