Identity in request, layout, home page, simple navigation to twig

parent 6ccc4e30
......@@ -26,6 +26,13 @@ $container['view'] = function ($c) {
$view->addExtension(new Knlv\Slim\Views\TwigMessages(
$c->get('flash')
));
if (isset($settings['navigation']) && is_array($settings['navigation'])) {
$view->addExtension(new GrEduLabs\Twig\Extension\Navigation(
$settings['navigation'],
$c->get('router'),
$c->get('request')
));
}
return $view;
};
......@@ -109,33 +116,14 @@ $container['authentication_service'] = function ($c) {
$container['authentication_cas_logout_middleware'] = function ($c) {
return new GrEduLabs\Middleware\CasLogout(
$c->get('authentication_service'),
$c->get('authentication_cas_adapter')
);
};
$container['maybe_identity'] = function ($c) {
return function ($call) use ($c) {
$authService = $c->get('authentication_service');
if (!$authService->hasIdentity()) {
return;
}
$identity = $authService->getIdentity();
if (method_exists($identity, $call)) {
$args = array_slice(func_get_args(), 1);
return call_user_func_array([$identity, $call], $args);
}
if (property_exists($identity, $call)) {
return $identity->{$call};
}
return;
};
$container['set_identity_in_request'] = function ($c) {
return new GrEduLabs\Middleware\SetIdentityInRequest(
$c->get('authentication_service')
);
};
// Inventory service
......@@ -150,6 +138,10 @@ $container['inventory_service'] = function ($c) {
// Actions
$container['GrEduLabs\\Action\\Index'] = function ($c) {
return new GrEduLabs\Action\Index($c->get('view'));
};
$container['GrEduLabs\\Action\\User\\Login'] = function ($c) {
$service = $service = $c->get('authentication_service');
$adapter = $c->get('authentication_db_adapter');
......
......@@ -8,5 +8,5 @@
*/
// Application middleware
// e.g: $app->add(new \Slim\Csrf\Guard);
$app->add('set_identity_in_request');
......@@ -7,22 +7,9 @@
* @license GNU GPLv3 http://www.gnu.org/licenses/gpl-3.0-standalone.html
*/
$app->get('/', function ($request, $response, $args) {
$logger = $this->get('logger');
$view = $this->get('view');
$identity = $this->get('maybe_identity');
$logger->info('Home page dispatched');
$view->render($response, 'home.twig', [
'user' => $identity('uid'),
]);
return $response;
})->setName('index');
$app->get('/', 'GrEduLabs\\Action\\Index')->setName('index');
// authentication
$app->group('/user', function () {
$this->map(['GET', 'POST'], '/login', 'GrEduLabs\\Action\\User\\Login')
......
<?php
/**
* gredu_labs
*
* @link https://github.com/eellak/gredu_labs for the canonical source repository
* @copyright Copyright (c) 2008-2015 Greek Free/Open Source Software Society (https://gfoss.ellak.gr/)
* @license GNU GPLv3 http://www.gnu.org/licenses/gpl-3.0-standalone.html
*/
namespace GrEduLabs\Action;
use Slim\Http\Request;
use Slim\Http\Response;
use Slim\Views\Twig;
class Index
{
/**
* @var Twig
*/
protected $view;
/**
* Constructor
* @param Twig $view
*/
public function __construct(Twig $view)
{
$this->view = $view;
}
public function __invoke(Request $req, Response $res)
{
return $this->view->render($res, 'index.twig');
}
}
......@@ -12,34 +12,28 @@ namespace GrEduLabs\Middleware;
use GrEduLabs\Authentication\Adapter\Cas;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Zend\Authentication\AuthenticationServiceInterface;
class CasLogout
{
/**
* @var AuthenticationServiceInterface
*/
protected $authService;
/**
* @var Cas
*/
protected $adapter;
public function __construct(AuthenticationServiceInterface $authService, Cas $adapter)
public function __construct(Cas $adapter)
{
$this->authService = $authService;
$this->adapter = $adapter;
$this->adapter = $adapter;
}
public function __invoke(ServerRequestInterface $req, ResponseInterface $res, callable $next)
{
if ($this->authService->hasIdentity()) {
$identity = $this->authService->getIdentity();
}
public function __invoke(
ServerRequestInterface $req,
ResponseInterface $res,
callable $next
) {
$identity = $req->getAttribute('identity');
$res = $next($req, $res);
if (isset($identity) && 'CAS' === $identity->authenticationSource) {
if ($identity && 'CAS' === $identity->authenticationSource) {
$this->adapter->logout($req->getUri());
}
......
<?php
/**
* gredu_labs
*
* @link https://github.com/eellak/gredu_labs for the canonical source repository
* @copyright Copyright (c) 2008-2015 Greek Free/Open Source Software Society (https://gfoss.ellak.gr/)
* @license GNU GPLv3 http://www.gnu.org/licenses/gpl-3.0-standalone.html
*/
namespace GrEduLabs\Middleware;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Zend\Authentication\AuthenticationServiceInterface;
class SetIdentityInRequest
{
/**
* @var AuthenticationServiceInterface
*/
protected $authService;
/**
* Constructor
* @param AuthenticationServiceInterface $authService
*/
public function __construct(AuthenticationServiceInterface $authService)
{
$this->authService = $authService;
}
public function __invoke(
ServerRequestInterface $req,
ResponseInterface $res,
callable $next
) {
if ($this->authService->hasIdentity()) {
$req = $req->withAttribute('identity', $this->authService->getIdentity());
}
return $next($req, $res);
}
}
<?php
/**
* gredu_labs
*
* @link https://github.com/eellak/gredu_labs for the canonical source repository
* @copyright Copyright (c) 2008-2015 Greek Free/Open Source Software Society (https://gfoss.ellak.gr/)
* @license GNU GPLv3 http://www.gnu.org/licenses/gpl-3.0-standalone.html
*/
namespace GrEduLabs\Twig\Extension;
use Psr\Http\Message\ServerRequestInterface;
use Slim\Interfaces\RouterInterface;
use Twig_Extension;
use Twig_SimpleFunction;
class Navigation extends Twig_Extension
{
/**
* @var RouterInterface
*/
private $router;
/**
* @var array
*/
private $navigation;
/**
* @var ServerRequestInterface
*/
private $request;
public function __construct(
array $navigation,
RouterInterface $router,
ServerRequestInterface $request
) {
$this->navigation = $navigation;
$this->router = $router;
$this->request = $request;
}
/**
* Extension name.
*
* @return string
*/
public function getName()
{
return 'slim-navigation';
}
/**
* Callback for twig.
*
* @return array
*/
public function getFunctions()
{
return [
new Twig_SimpleFunction('nav', [$this, 'nav']),
];
}
/**
*
*/
public function nav($root = null)
{
$navigation = (null !== $root) ? $this->navigation[$root] : $this->navigation;
$prepare = function ($page) use (&$prepare) {
if (isset($page['route'])) {
$routeData = isset($page['route_data']) ? $page['route_data'] : [];
$query = isset($page['query']) ? $page['query'] : [];
$page['href'] = $this->router->pathFor($page['route'], $routeData, $query);
}
$uri = $this->request->getUri();
$path = $uri->getPath();
$page['active'] = $path === parse_url($page['href'], PHP_URL_PATH);
if (isset($page['pages']) && is_array($page['pages'])) {
$page['pages'] = array_map($prepare, $page['pages']);
}
return $page;
};
return array_map($prepare, $navigation);
}
}
{% extends "layout.twig" %}
{% block content %}
Welcome {{ user }}
<a href="{{ path_for('user.login') }}">Login</a>
{% endblock %}
\ No newline at end of file
{% extends "layout.twig" %}
{% block content %}
<div class="jumbotron">
<h1>Σχολικά εργαστήρια</h1>
<p class="lead">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam vel volutpat diam, vitae consectetur libero. Sed et sem et nisi aliquet condimentum. Morbi id magna iaculis, dictum lectus vitae, suscipit nisl. Proin molestie dolor vitae pulvinar tristique. Integer egestas varius lorem id scelerisque. Praesent velit metus, egestas facilisis iaculis id, auctor nec mi. Suspendisse ultrices laoreet justo eget viverra.</p>
<p><a class="btn btn-lg btn-success" href="{{ path_for('user.login') }}" role="button">Σύνδεση</a></p>
</div>
{% endblock %}
\ No newline at end of file
......@@ -5,10 +5,33 @@
<title>GrEduLabs</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
<link href="{{ base_url() }}/css/style.css" rel="stylesheet" type="text/css">
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" href="{{ base_url }}/img/favicon.ico">
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
<link href="{{ base_url }}/css/ie10-viewport-bug-workaround.css" rel="stylesheet" type="text/css">
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
{% include 'flash.twig' %}
{% block content %}{% endblock %}
<body class="">
<div class="container">
<div class="header clearfix">
{% include 'navigation/main.twig' %}
<h3 class="text-muted">GrEduLabs</h3>
</div>
<div id="content">
{% include 'flash.twig' %}
{% block content %}{% endblock %}
</div>
<footer class="footer">
<p>
&copy; 2008-{{ "now"|date("Y") }} <a href="https://gfoss.ellak.gr/" target="_blank">Greek Free/Open Source Software Society</a>
</p>
</footer>
</div>
<script src="//code.jquery.com/jquery-2.2.0.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous"></script>
{% block inlinejs %}{% endblock %}
......
<nav>
<ul class="nav nav-pills pull-right">
{% for page in nav('main') %}
<li role="presentation" class="{% if page.active %}active{% endif %}">
<a href="{{ page.href }}">{{ page.label }}</a>
</li>
{% endfor %}
</ul>
</nav>
\ No newline at end of file
{% extends "layout.twig" %}
{% block content %}
<form method="post" action="{{ path_for('user.login') }}" id="user-login-form" class="form-horizontal">
<div class="form-group">
<label class="hidden-sm col-sm-2 control-label">Email</label>
<div class="col-xs-12 col-sm-5">
<div class="input-group">
<span class="input-group-addon">@</span>
<input name="identity" type="text" value="" class="form-control" required autocomplete="off">
<h1>Σύνδεση</h1>
<div class="row">
<div class="col-sm-12 col-md-6">
<p>Για την σύνδεση των σχολικών μονάδων ή αν επιθυμείτε να συνδεθείτε μέσω το Πανελληνίου Σχολικού Δικτύου.</p>
<hr>
<p class="text-center">
<a class="btn btn-lg btn-success" href="{{ path_for('user.loginSso') }}" role="button">Σύνδεση sch.gr</a>
</p>
</div>
<div class="clearfix visible-sm"></div>
<div class="col-sm-12 col-md-6">
<p>Αν έχετε ήδη δημιουργήσει λογαριασμό στο σύστημα, συνδεθείτε εδώ.</p>
<form method="post" action="{{ path_for('user.login') }}" id="user-login-form" class="form-horizontal">
<div class="form-group">
<label class="hidden-sm col-sm-3 control-label">Email</label>
<div class="col-xs-12 col-sm-9">
<div class="input-group">
<span class="input-group-addon">@</span>
<input name="identity" type="text" value="" class="form-control" required autocomplete="off">
</div>
</div>
</div>
</div>
<div class="form-group">
<label class="hidden-sm col-sm-2 control-label">Password</label>
<div class="col-xs-12 col-sm-5">
<div class="input-group">
<span class="input-group-addon">
<i class="glyphicon glyphicon-lock"></i>
</span>
<input name="credential" type="password" value="" class="form-control" required autocomplete="off">
<div class="form-group">
<label class="hidden-sm col-sm-3 control-label">Password</label>
<div class="col-xs-12 col-sm-9">
<div class="input-group">
<span class="input-group-addon">
<i class="glyphicon glyphicon-lock"></i>
</span>
<input name="credential" type="password" value="" class="form-control" required autocomplete="off">
</div>
</div>
</div>
<hr>
<div class="form-group text-center">
<button type="submit" name="login_method" value="credentials" class="btn btn-primary">Σύνδεση</button>
</div>
<input type="hidden" name="{{ csrf_name_key }}" value="{{ csrf_name }}">
<input type="hidden" name="{{ csrf_value_key }}" value="{{ csrf_value }}">
</form>
</div>
<hr>
<div class="form-group">
<button type="submit" name="login_method" value="credentials" class="btn btn-primary">Sing in</button>
<a href="{{ path_for('user.loginSso') }}" class="btn bnt-default">SSO</a>
</div>
<input type="hidden" name="{{ csrf_name_key }}" value="{{ csrf_name }}">
<input type="hidden" name="{{ csrf_value_key }}" value="{{ csrf_value }}">
</form>
</div>
{% endblock %}
\ No newline at end of file
......@@ -149,16 +149,16 @@
},
{
"name": "guzzlehttp/psr7",
"version": "1.2.1",
"version": "1.2.2",
"source": {
"type": "git",
"url": "https://github.com/guzzle/psr7.git",
"reference": "4d0bdbe1206df7440219ce14c972aa57cc5e4982"
"reference": "f5d04bdd2881ac89abde1fb78cc234bce24327bb"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/psr7/zipball/4d0bdbe1206df7440219ce14c972aa57cc5e4982",
"reference": "4d0bdbe1206df7440219ce14c972aa57cc5e4982",
"url": "https://api.github.com/repos/guzzle/psr7/zipball/f5d04bdd2881ac89abde1fb78cc234bce24327bb",
"reference": "f5d04bdd2881ac89abde1fb78cc234bce24327bb",
"shasum": ""
},
"require": {
......@@ -203,7 +203,7 @@
"stream",
"uri"
],
"time": "2015-11-03 01:34:55"
"time": "2016-01-23 01:23:02"
},
{
"name": "jasig/phpcas",
......@@ -1274,16 +1274,16 @@
},
{
"name": "fabpot/php-cs-fixer",
"version": "v1.11",
"version": "v1.11.1",
"source": {
"type": "git",
"url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git",
"reference": "bd3ec2c2b774e0e127ac2c737ec646d9cf2f9eef"
"reference": "2c9f8298181f059c5077abda78019b9a0c9a7cc0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/bd3ec2c2b774e0e127ac2c737ec646d9cf2f9eef",
"reference": "bd3ec2c2b774e0e127ac2c737ec646d9cf2f9eef",
"url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/2c9f8298181f059c5077abda78019b9a0c9a7cc0",
"reference": "2c9f8298181f059c5077abda78019b9a0c9a7cc0",
"shasum": ""
},
"require": {
......@@ -1324,7 +1324,7 @@
}
],
"description": "A tool to automatically fix PHP code style",
"time": "2015-12-01 22:34:33"
"time": "2016-01-20 19:00:28"
},
{
"name": "phpdocumentor/reflection-docblock",
......@@ -1861,12 +1861,12 @@
"source": {
"type": "git",
"url": "https://github.com/satooshi/php-coveralls.git",
"reference": "536b23de186ff3e04a138a8d3efbc526946964c4"
"reference": "50c60bb64054974f8ed7540ae6e75fd7981a5fd3"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/satooshi/php-coveralls/zipball/536b23de186ff3e04a138a8d3efbc526946964c4",
"reference": "536b23de186ff3e04a138a8d3efbc526946964c4",
"url": "https://api.github.com/repos/satooshi/php-coveralls/zipball/50c60bb64054974f8ed7540ae6e75fd7981a5fd3",
"reference": "50c60bb64054974f8ed7540ae6e75fd7981a5fd3",
"shasum": ""
},
"require": {
......@@ -1875,10 +1875,10 @@
"guzzlehttp/guzzle": "^6.0",
"php": ">=5.5",
"psr/log": "^1.0",
"symfony/config": "^2.4|^3.0",
"symfony/config": "^2.1|^3.0",
"symfony/console": "^2.1|^3.0",
"symfony/stopwatch": "^2.2|^3.0",
"symfony/yaml": "^2.1|^3.0"
"symfony/stopwatch": "^2.0|^3.0",
"symfony/yaml": "^2.0|^3.0"
},
"suggest": {
"symfony/http-kernel": "Allows Symfony integration"
......@@ -1916,7 +1916,7 @@
"github",
"test"
],
"time": "2016-01-04 18:41:30"
"time": "2016-01-20 17:44:41"
},
{
"name": "sebastian/comparator",
......@@ -2152,21 +2152,21 @@
},
{
"name": "sebastian/finder-facade",
"version": "1.1.0",
"version": "1.2.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/finder-facade.git",
"reference": "1e396fda3449fce9df032749fa4fa2619e0347e0"
"reference": "a520dcc3dd39160eea480daa3426f4fd419a327b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/finder-facade/zipball/1e396fda3449fce9df032749fa4fa2619e0347e0",
"reference": "1e396fda3449fce9df032749fa4fa2619e0347e0",
"url": "https://api.github.com/repos/sebastianbergmann/finder-facade/zipball/a520dcc3dd39160eea480daa3426f4fd419a327b",
"reference": "a520dcc3dd39160eea480daa3426f4fd419a327b",
"shasum": ""
},
"require": {
"symfony/finder": ">=2.2.0",
"theseer/fdomdocument": ">=1.3.1"
"symfony/finder": "~2.3",
"theseer/fdomdocument": "~1.3"
},
"type": "library",
"autoload": {
......@@ -2187,7 +2187,7 @@
],
"description": "FinderFacade is a convenience wrapper for Symfony's Finder component.",
"homepage": "https://github.com/sebastianbergmann/finder-facade",
"time": "2013-05-28 06:10:03"
"time": "2015-06-04 08:11:58"
},
{
"name": "sebastian/global-state",
......@@ -2549,25 +2549,25 @@
},
{
"name": "symfony/finder",
"version": "v3.0.1",
"version": "v2.8.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/finder.git",
"reference": "8617895eb798b6bdb338321ce19453dc113e5675"
"reference": "c90fabdd97e431ee19b6383999cf35334dff27da"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/finder/zipball/8617895eb798b6bdb338321ce19453dc113e5675",
"reference": "8617895eb798b6bdb338321ce19453dc113e5675",
"url": "https://api.github.com/repos/symfony/finder/zipball/c90fabdd97e431ee19b6383999cf35334dff27da",
"reference": "c90fabdd97e431ee19b6383999cf35334dff27da",
"shasum": ""
},
"require": {
"php": ">=5.5.9"
"php": ">=5.3.9"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.0-dev"
"dev-master": "2.8-dev"
}
},
"autoload": {
......@@ -2594,20 +2594,20 @@
],
"description": "Symfony Finder Component",
"homepage": "https://symfony.com",
"time": "2015-12-05 11:13:14"
"time": "2016-01-14 08:26:52"
},
{
"name": "symfony/polyfill-mbstring",
"version": "v1.0.1",
"version": "v1.1.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "49ff736bd5d41f45240cec77b44967d76e0c3d25"
"reference": "1289d16209491b584839022f29257ad859b8532d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/49ff736bd5d41f45240cec77b44967d76e0c3d25",
"reference": "49ff736bd5d41f45240cec77b44967d76e0c3d25",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/1289d16209491b584839022f29257ad859b8532d",
"reference": "1289d16209491b584839022f29257ad859b8532d",
"shasum": ""
},
"require": {
......@@ -2619,7 +2619,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0-dev"
"dev-master": "1.1-dev"
}
},
"autoload": {
......@@ -2653,7 +2653,7 @@
"portable",
"shim"
],
"time": "2015-11-20 09:19:13"
"time": "2016-01-20 09:13:37"
},
{
"name": "symfony/process",
......
<?php return [
'navigation' => [
'main' => [
[
'label' => 'Αρχική',
'route' => 'index',
],
[
'label' => 'Σύνδεση',
'route' => 'user.login',
],
],
],
];
/*!
* IE10 viewport hack for Surface/desktop Windows 8 bug
* Copyright 2014-2015 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*/
/*
* See the Getting Started docs for more information:
* http://getbootstrap.com/getting-started/#support-ie10-width
*/
@-webkit-viewport { width: device-width; }
@-moz-viewport { width: device-width; }
@-ms-viewport { width: device-width; }
@-o-viewport { width: device-width; }
@viewport { width: device-width; }
\ No newline at end of file
/* Space out content a bit */
body {
padding-top: 20px;
padding-bottom: 20px;