Completed
Push — master ( 2f80ed...483e11 )
by Jeff
03:21
created

AuthController::kerberosAuth()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 10
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 10
rs 9.4285
cc 3
eloc 4
nc 2
nop 0
1
<?php
2
3
namespace app\controllers;
4
5
use Yii;
6
use yii\filters\AccessControl;
7
use app\models\User;
8
use app\models\UserLogin;
9
10
/**
11
 * AuthController implements the authentication methods.
12
 */
13
class AuthController extends BaseController
14
{
15
    /**
16
     * {@inheritdoc}
17
     */
18
    public function behaviors()
19
    {
20
        return [
21
            'access' => [
22
                'class' => AccessControl::className(),
23
                'only' => ['login', 'logout'],
24
                'rules' => [
25
                    ['allow' => true, 'actions' => ['login'], 'roles' => ['?']],
26
                    ['allow' => true, 'actions' => ['logout'], 'roles' => ['@']],
27
                ],
28
            ],
29
        ];
30
    }
31
32
    /**
33
     * {@inheritdoc}
34
     */
35
    public function init()
36
    {
37
        parent::init();
38
39
        // Catch login event to afterLogin method
40
        Yii::$app->user->on(\yii\web\User::EVENT_AFTER_LOGIN, ['app\models\User', 'afterLogin']);
41
    }
42
43
    /**
44
     * Index redirects to login action.
45
     *
46
     * @return \yii\web\Reponse|string redirect or render
47
     */
48
    public function actionIndex()
49
    {
50
        return $this->actionLogin();
51
    }
52
53
    /**
54
     * Login an user based on kerberos auth if available, else use login form
55
     * with LDAP backend if available or DB.
56
     *
57
     * @return \yii\web\Reponse|string redirect or render
58
     */
59
    public function actionLogin()
60
    {
61
        if (!Yii::$app->user->isGuest) {
62
            return $this->goBack();
63
        }
64
65
        // Kerberos auth
66
        $identity = $this->getFromKerberos();
0 ignored issues
show
Documentation Bug introduced by
The method getFromKerberos does not exist on object<app\controllers\AuthController>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
67
        if ($identity) {
68
            // Login auto saves in DB
69
            Yii::$app->user->login($identity, Yii::$app->params['cookieDuration']);
70
71
            return $this->goBack();
72
        }
73
74
        // User login form
75
        $model = new UserLogin();
76
        if ($model->load(Yii::$app->request->post()) && $model->validate()) {
77
            // Find in DB/LDAP
78
            $identity = User::findIdentity($model->username);
79
            // Authenticate
80
            if ($identity !== null && $identity->authenticate($model->password)) {
81
                Yii::$app->user->enableAutoLogin = $model->remember_me;
82
                // Login auto saves in DB
83
                Yii::$app->user->login($identity, Yii::$app->params['cookieDuration']);
84
85
                return $this->goBack();
86
            }
87
            $model->addError('username', Yii::t('app', 'Username or password incorrect'));
88
        }
89
90
        return $this->render('login', [
91
            'model' => $model,
92
        ]);
93
    }
94
95
    /**
96
     * Check for kerberos configuration and try to authenticate user.
97
     *
98
     * @return \app\models\User|null found user
99
     */
100
    private function kerberosAuth()
0 ignored issues
show
Coding Style introduced by
kerberosAuth 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...
101
    {
102
        // Kerberos auth
103
        if (Yii::$app->params['useKerberos'] && isset($_SERVER[Yii::$app->params['kerberosPrincipalVar']])) {
104
            $username = $_SERVER[Yii::$app->params['kerberosPrincipalVar']];
105
106
            // Find in DB/LDAP
107
            return User::findIdentity($username);
108
        }
109
    }
110
111
    /**
112
     * Disconnects current user.
113
     *
114
     * @return \yii\web\Reponse
115
     */
116
    public function actionLogout()
117
    {
118
        if (Yii::$app->user->isGuest) {
119
            return $this->goBack();
120
        }
121
122
        Yii::$app->user->logout();
123
124
        return $this->goHome();
125
    }
126
}
127