CASLogin.php 11 KB
Newer Older
1
2
3
4
5
6
7
<?php
namespace Drupal\casost\Controller;

use Drupal\Core\Entity\Query\QueryFactory;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Controller\ControllerBase;
8
use phpCAS;
9
10
11
12
13
14
15
use Drupal\user\Entity\User;
use Drupal\Core\Database\Connection;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Drupal\Core\Logger\LoggerChannelFactoryInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\RedirectResponse;
16
17
use Symfony\Component\HttpFoundation\Cookie;
require ('RedirectResponseWithCookie.php');
18
19
20
21
22
23
24
25

class CASLogin extends ControllerBase
{

    protected $serverVersion;
    protected $serverHostname;
    protected $serverPort;
    protected $serverUri;
26
    protected $redirectUrl;
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
    protected $changeSessionId;
    protected $CASServerCACert;
    protected $CASServerCNValidate;
    protected $noCASServerValidation;
    protected $proxy;
    protected $handleLogoutRequests;
    protected $CASLang;
    protected $allowed1;
    protected $allowed1Value;
    protected $allowed2;
    protected $allowed2Value;

    protected $entity_query;
    protected $entityTypeManager;
    protected $logger;
    protected $connection;

    public function __construct(
    EntityTypeManagerInterface $entityTypeManager,
    QueryFactory $entity_query,
    Connection $connection,
    LoggerChannelFactoryInterface $loggerChannel)
    {
        $this->entityTypeManager = $entityTypeManager;
        $this->entity_query = $entity_query;
        $this->connection = $connection;
        $this->logger = $loggerChannel->get('casost');

    }

57
58


59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
    public static function create(ContainerInterface $container)
    {
        return new static(
          $container->get('entity.manager'),
          $container->get('entity.query'),
          $container->get('database'),
          $container->get('logger.factory')
      );
    }

    public function loginGo(Request $request)
    {

        try {

74
75
76
77
78
79
80
            $CASOSTConfigs = $this->entityTypeManager->getStorage('casost_config')->loadByProperties(array('name' => 'casost_sch_sso_config'));
            $CASOSTConfig = reset($CASOSTConfigs);
            if ($CASOSTConfig) {
                $this->serverVersion = $CASOSTConfig->serverversion->value;
                $this->serverHostname = $CASOSTConfig->serverhostname->value;
                $this->serverPort = $CASOSTConfig->serverport->value;
                $this->serverUri = $CASOSTConfig->serveruri->value === null ? '' : $CASOSTConfig->serveruri->value;
81
                $this->redirectUrl = $CASOSTConfig->redirecturl->value;
82
83
84
85
86
87
88
89
90
91
92
93
                $this->changeSessionId = $CASOSTConfig->changesessionid->value;
                $this->CASServerCACert = $CASOSTConfig->casservercacert->value;
                $this->CASServerCNValidate = $CASOSTConfig->casservercnvalidate->value;
                $this->noCASServerValidation = $CASOSTConfig->nocasservervalidation->value;
                $this->proxy = $CASOSTConfig->proxy->value;
                $this->handleLogoutRequests = $CASOSTConfig->handlelogoutrequests->value;
                $this->CASLang = $CASOSTConfig->caslang->value;
                $this->allowed1 = $CASOSTConfig->allowed1->value;
                $this->allowed1Value = $CASOSTConfig->allowed1value->value;
                $this->allowed2 = $CASOSTConfig->allowed2->value;
                $this->allowed2Value = $CASOSTConfig->allowed2value->value;
            }
94
            phpCAS::setDebug("/home/haris/devel/eepal/drupal/modules/casost/phpcas.log");
95
            // Enable verbose error messages. Disable in production!
96
            phpCAS::setVerbose(true);
97

98
            phpCAS::client($this->serverVersion,
99
100
101
102
103
                $this->serverHostname,
                intval($this->serverPort),
                $this->serverUri,
                boolval($this->changeSessionId));

104

105
106
107
108
109
//            \phpCAS::setServerLoginURL('http://sso-test.sch.gr/login');
//            \phpCAS::setServerServiceValidateURL('http://sso-test.sch.gr/cas/samlValidate');

            if ($this->CASServerCACert) {
                if ($this->CASServerCNValidate) {
110
                    phpCAS::setCasServerCACert($this->CASServerCACert, true);
111
                } else {
112
                    phpCAS::setCasServerCACert($this->CASServerCACert, false);
113
114
115
                }
            }
            if ($this->noCASServerValidation) {
116
                phpCAS::setNoCasServerValidation();
117
            }
118
119
            phpCAS::handleLogoutRequests();
            if (!phpCAS::forceAuthentication()) {
120
121
122
123
124
125
                $response = new Response();
                $response->setContent('forbidden. cannot force authentication');
                $response->setStatusCode(Response::HTTP_FORBIDDEN);
                $response->headers->set('Content-Type', 'application/json');
                return $response;
            }
126
            $attributes = phpCAS::getAttributes();
127
128
129
130
            foreach ($attributes as $attr_key => $attr_value) {
                $this->logger->warning($attr_key);
                $this->logger->warning(phpCAS::getAttribute($attr_key));
            }
131

132
/*            $isAllowed = true;
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
            $att1 = $attributes[$this->allowed1];
            $att2 = $attributes[$this->allowed2];
            if (!isset($att1) || !isset($att2)) {
                $isAllowed = false;
            }
            if (!is_array($attributes[$this->allowed1])) {
                $attributes[$this->allowed1] = [$attributes[$this->allowed1]];
            }
            if (!is_array($attributes[$this->allowed2])) {
                $attributes[$this->allowed2] = [$attributes[$this->allowed2]];
            }
            $found1 = false;
            foreach ($attributes[$this->allowed1] as $value) {
                if (1 === preg_match($this->allowed1Value, $value)) {
                    $found1 = true;
                }
            }
            $found2 = false;
            foreach ($attributes[$this->allowed2] as $value) {
                if (1 === preg_match($this->allowed2Value, $value)) {
                    $found2 = true;
                }
            }
            if (!$found1 || !$found2) {
                $isAllowed = false;
158
            } */
159
160
161
162
163
164
165
166

    /*        if (!$isAllowed) {
                $response = new Response();
                $response->setContent(t('Access is allowed only to official school accounts'));
                $response->setStatusCode(Response::HTTP_FORBIDDEN);
                $response->headers->set('Content-Type', 'application/json;charset=UTF-8');
                return $response;
            } */
167
            $CASUser = phpCAS::getUser();
168
169
170
171
172

            $this->logger->warning($CASUser);

            $filterAttribute = function ($attribute) use ($attributes) {
                if (!isset($attributes[$attribute])) {
173
                    return false;
174
175
176
177
                }
                return $attributes[$attribute];
            };

178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
            $exposedRole = 'director';
            $internalRole = 'epal';
            $CASTitle = preg_replace('/\s+/', '', $filterAttribute('title'));
            if ($CASTitle === 'ΠΕΡΙΦΕΡΕΙΑΚΗΔΙΕΥΘΥΝΣΗΕΚΠΑΙΔΕΥΣΗΣ-ΠΔΕ') {
                $exposedRole = 'pde';
                $internalRole = 'regioneduadmin';
            } else if ($CASTitle === 'ΔΙΕΥΘΥΝΣΗΔΕ-ΔIΔΕ') {
                $exposedRole = 'dide';
                $internalRole = 'eduadmin';
            } else if ($CASTitle === 'ΕΠΑΛ') {
                $exposedRole = 'director';
                $internalRole = 'epal';
            } else {
                $response = new Response();
                $this->logger->warning(t('Access is allowed only to official school accounts or administration'));
                $response->setContent(t('Access is allowed only to official school accounts or administration'));
                $response->setStatusCode(Response::HTTP_FORBIDDEN);
                $response->headers->set('Content-Type', 'application/json;charset=UTF-8');
                return $response;
            }

199
// $this->logger->warning('cn=' . $filterAttribute('cn'));
200
            $epalToken = $this->authenticatePhase2($request, $CASUser, $internalRole, $filterAttribute('cn'));
201
            if ($epalToken) {
202
                $cookie = new Cookie('auth_token', $epalToken, 0, '/', null, false, false);
203
                $cookie2 = new Cookie('auth_role', $exposedRole, 0, '/', null, false, false);
204
205
206
207

                return new RedirectResponseWithCookie($this->redirectUrl, 302, array ($cookie, $cookie2));
//                $headers = array("auth_token" => $epalToken, "auth_role" => "director");
//                return new RedirectResponse($this->redirectUrl, 302, $headers);
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
            } else {
                $response = new Response();
                $response->setContent('forbidden');
                $response->setStatusCode(Response::HTTP_FORBIDDEN);
                $response->headers->set('Content-Type', 'application/json');
                return $response;
            }

        } catch (\Exception $e) {
            $this->logger->warning($e->getMessage());
            $response = new Response();
            $response->setContent('forbidden');
            $response->setStatusCode(Response::HTTP_FORBIDDEN);
            $response->headers->set('Content-Type', 'application/json');
            return $response;
        }
    }

226
    public function authenticatePhase2($request, $CASUser, $internalRole, $cn)
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
    {
    $trx = $this->connection->startTransaction();
    try {

        $currentTime = time();

        $epalToken = md5(uniqid(mt_rand(), true));

            $users = $this->entityTypeManager->getStorage('user')->loadByProperties(array('mail' => $CASUser));
            $user = reset($users);
            if ($user) {
                $user->setPassword($epalToken);
                $user->setUsername($epalToken);
                $user->save();
            }


        if ($user === null || !$user) {

            //Create a User
            $user = User::create();
            //Mandatory settings
            $unique_id = uniqid('####');
            $user->setPassword($epalToken);
            $user->enforceIsNew();
            $user->setEmail($CASUser);
            $user->setUsername($epalToken); //This username must be unique and accept only a-Z,0-9, - _ @ .
            $user->activate();
255
            $user->set('init', $cn);
256
257
258
259
260
261
262
263

            //Set Language
            $language_interface = \Drupal::languageManager()->getCurrentLanguage();
            $user->set('langcode', $language_interface->getId());
            $user->set('preferred_langcode', $language_interface->getId());
            $user->set('preferred_admin_langcode', $language_interface->getId());

            //Adding default user role
264
            $user->addRole($internalRole);
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
            $user->save();
        }

        return $epalToken;
    } catch (OAuthException $e) {
        $this->logger->warning($e->getMessage());
        $trx->rollback();
        return false;
    } catch (\Exception $ee) {
        $this->logger->warning($ee->getMessage());
        $trx->rollback();
        return false;
    }

        return false;
    }

}