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;
    }

}