Completed
Push — master ( 5d1105...8d5fa1 )
by Konstantinos
18:00
created

controllers/LoginController.php (2 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 11 and the first side effect is on line 9.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
3
use BZIon\Composer\ConfigHandler;
4
use Symfony\Component\HttpFoundation\RedirectResponse;
5
use Symfony\Component\HttpFoundation\Request;
6
use Symfony\Component\HttpFoundation\Session\Session;
7
use Symfony\Component\Yaml\Yaml;
8
9 1
require_once __DIR__ . '/../includes/checkToken.php';
10
11
class LoginController extends HTMLController
12
{
13 1
    public function loginAction(Request $request, Player $me)
14
    {
15 1
        if ($me->isValid()) {
16
            throw new ForbiddenException("You are already logged in!");
17
        }
18
19 1
        $query = $request->query;
20 1
        $session = $request->getSession();
21
22 1
        $token = $query->get("token");
23 1
        $username = $query->get("username");
24
25 1
        if (!$token || !$username) {
26 1
            throw new BadRequestException();
27
        }
28
29
        // Don't check whether IPs match if we're on a development environment
30
        $checkIP = !$this->isDebug();
31
        $info = validate_token($token, $username, array(), $checkIP);
32
33
        if (!isset($info)) {
34
            throw new ForbiddenException("There was an error processing your login. Please go back and try again.");
35
        }
36
37
        $session->set("username", $info['username']);
38
        $session->set("groups", $info['groups']);
39
40
        $redirectToProfile = false;
41
42
        if (!Player::playerBZIDExists($info['bzid'])) {
43
            // If they're new, redirect to their profile page so they can add some info
44
            $player = Player::newPlayer($info['bzid'], $info['username']);
45
            $redirectToProfile = true;
46
        } else {
47
            $player = Player::getFromBZID($info['bzid']);
48
        }
49
50
        $session->set("playerId", $player->getId());
51
        $player->updateLastLogin();
52
53
        $player->setUsername($info['username']);
54
        Visit::enterVisit($player->getId(),
55
                          $request->getClientIp(),
56
                          gethostbyaddr($request->getClientIp()),
57
                          $request->server->get('HTTP_USER_AGENT'),
58
                          $request->server->get('HTTP_REFERER'));
59
        $this->configPromoteAdmin($player);
0 ignored issues
show
It seems like $player defined by \Player::getFromBZID($info['bzid']) on line 47 can be null; however, LoginController::configPromoteAdmin() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
60
61
        if ($redirectToProfile) {
62
            $profile = Service::getGenerator()->generate('profile_show');
63
64
            return new RedirectResponse($profile);
65
        } else {
66
            return $this->goBack();
67
        }
68
    }
69
70 1
    public function logoutAction(Session $session)
71
    {
72 1
        $session->invalidate();
73 1
        $session->getFlashBag()->add('success', "You logged out successfully");
74
75
        // Don't redirect back but prefer going home, to prevent visiting
76
        // the login page (and logging in again, thus preventing the logout)
77
        // or other pages where authentication is required
78 1
        return $this->goHome();
79
    }
80
81
    public function loginAsTestUserAction(Session $session, Player $user)
82
    {
83
        if (!$user->isTestUser()) {
84
            throw new Exception("The player you specified is not a test user!");
85
        }
86
87
        $session->set("playerId", $user->getId());
88
        $session->set("username", $user->getUsername());
89
90
        return $this->goHome();
91
    }
92
93
    /**
94
     * Promote a player to an admin if the configuration file specifies so
95
     *
96
     * @param Player $player The player in question
97
     */
98
    private function configPromoteAdmin(Player $player)
99
    {
100
        $adminUsername = $this->container->getParameter('bzion.miscellaneous.admin');
101
102
        if (!$adminUsername) {
103
            return;
104
        }
105
106
        if (strtolower($player->getUsername()) === strtolower($adminUsername)) {
107
            $player->addRole(Player::DEVELOPER);
108
109
            // Remove the username from the configuration file so that we don't
110
            // give admin permissions to the wrong person in case callsign
111
            // changes take place. This is supposed to happen only once, so we
112
            // don't need to worry about the performance overhead due to the
113
            // parsing and dumping of the YML file
114
            $path = ConfigHandler::getConfigurationPath();
115
            $config = Yaml::parse($path);
116
            $config['bzion']['miscellaneous']['admin'] = null;
117
            file_put_contents($path, Yaml::dump($config, 4));
118
119
            $this->getLogger()->notice(sprintf(
120
                "User %s with BZID %s is now an administrator, as instructed by the configuration file",
121
                $adminUsername,
122
                $player->getBZID()
123
            ));
124
        }
125
    }
126
}
127