Commit e4d55d11 authored by François Agneray's avatar François Agneray
Browse files

Merge branch 'develop' into 'master'

Develop

See merge request cesamSI/jdev-boarding!1
parents 9cb982d5 ce1b8553
FROM php:7.3-apache
# Install modules
RUN apt-get update \
&& apt-get install -y zlib1g zlib1g-dev libpq-dev libpq5 libzip-dev zip unzip \
&& docker-php-ext-install pgsql pdo_pgsql zip
RUN a2enmod rewrite
COPY . /srv/app
COPY ./conf-dev/vhost.conf /etc/apache2/sites-available/000-default.conf
WORKDIR /srv/app
CMD ["apache2-foreground"]
UID := 1000
GID := 1000
list:
@echo ""
@echo "Useful targets:"
@echo ""
@echo " install_php > install php composer dependancies"
@echo " install_frontend > install frontend dependancies (js, css...)"
@echo " up > build php image and start jdev-boarding containers for dev only (php + mailer)"
@echo " start > start jdev-boarding containers"
@echo " restart > restart jdev-boarding containers"
@echo " stop > stop and kill running jdev-boarding containers"
@echo " logs > display jdev-boarding containers logs"
@echo " shell > shell into php jdev-boarding container"
@echo " gendb > generate the jdev-boarding database"
@echo " remove-pgdata > remove the volume of database"
@echo ""
install_php:
@docker run --init -it --rm --user $(UID):$(GID) \
-e COMPOSER_CACHE_DIR=/dev/null \
-v $(CURDIR):/project \
-w /project jakzal/phpqa composer install --ignore-platform-reqs
install_frontend:
@docker build -t jdev-bower conf-dev/npm && docker run --init -it --rm --user $(UID):$(GID) \
-v $(CURDIR):/project \
-w /project jdev-bower bower install
up:
@docker-compose up --build -d
start:
@docker-compose up -d
restart: stop start
stop:
@docker-compose kill
@docker-compose rm -v --force
logs:
@docker-compose logs -f -t
shell:
@docker-compose exec php bash
gendb:
@docker-compose exec php ./vendor/bin/doctrine orm:schema-tool:create
remove-pgdata:
@docker volume rm jdev-boarding_pgdata
# JDEV BOARDING
## Introduction
Jdev-boarding est le logiciel utilisé pour les inscriptions et le suivi de l'évenement des JDEVs.
Le logiciel jdev-boarding est sous licence `CeCILL` (voir le fichier LICENCE à la racine du projet).
## Authors
Voici la liste des personnes ayant participées au projet jdev-boarding:
* `Chrystel Moreau` : Laboratoire d'Astrophysique de Marseille (CNRS)
* `François Agneray` : Laboratoire d'Astrophysique de Marseille (CNRS)
# Guide d'installation
## Prérequis
Avant de vous lancer dans l'installation du logiciel jdev-boarding sur votre machine, vous devez vous assurer que les commandes suivantes sont installées sur votre ordinateur:
1. `make`
2. `docker`
3. `docker-compose`
Vous aurez également besoin d'une connexion Internet pour effectuer l'installation.
## La liste des commandes
Le fichier `Makefile` que vous pouvez trouver à la racine du projet contient l'ensemble des commandes disponibles et qui vous aiderons dans l'installation et le démarrage du logiciel.
Pour voir la liste des commandes possibles vous pouvez ouvrir un terminal et taper:
> make
**Attention**: Le fichier `docker-compose.yml` et les commandes du ` Makefile` ne doivent être utilisées que pour le dévloppement et non pas dans un mode production.
## Installation des dépendances
Pour effectuer l'installation des dépendances php et des dépendances `frontend` (js, css...), tapez:
> make install_php
L'outil `Composer.phar` va télécharger automatiquement les dépendances php qui sont listées dans le fichier `composer.json`. Les dépendances seront stockées dans un dossier `vendor` du projet.
> make install_frontend
L'outil `bower` va télécharger automatiquement les dépendances front (js, css) qui sont listées dans le fichier `bower.json`.
Les dépendandes seront stockées dans un dossier `public/bower_components` du projet.
Après cela jdev-boarding peut fonctionner.
## Lancement du jdev-boarding
Jdev-boarding est configuré pour fonctionner dans un environnement docker. Si vous ouvrez le fichier `docker-compose.yml` vous pouvez voir les conteneurs qui sont utilisés dans le mode développement.
`Makefile` fournit une liste de commandes pour builder et lancer les conteneurs:
> make up
**Note:** Cette commande utilise le fichier `docker-compose` pour fonctionner. Les opérations peuvent prendre quelques minutes car cela nécessite de télécharger des images sur le docker hub.
Vous pouvez lister les conteneurs qui tournent sur votre machine:
> docker-compose ps
Vous pouvez aussi afficher les logs des conteneurs lancés:
> make logs
## Installation de la base de données
Jdev-boarding à besoin d'une base de données pour fonctionner.
Pour pouvoir générer les tables automatiquement vous pouvez lancer la commane suivante:
> make gendb
## Accès
Vous poucez maintenant vous rendre sur votre navigateur pour afficher le boarding:
> http://localhost:8080
3.5
\ No newline at end of file
4.0
\ No newline at end of file
......@@ -57,12 +57,8 @@ $container[App\Action\InscriptionAction::class] = function ($c) {
return new App\Action\InscriptionAction($c->get('view'), $c->get('logger'), $c->get('em'), $c->get('mailer'), $c->get('settings'));
};
$container[App\Action\ConfirmInscriptionAction::class] = function ($c) {
return new App\Action\ConfirmInscriptionAction($c->get('view'), $c->get('logger'), $c->get('em'), $c->get('mailer'));
};
$container[App\Action\ConnexionAction::class] = function ($c) {
return new App\Action\ConnexionAction($c->get('view'), $c->get('logger'), $c->get('em'));
return new App\Action\ConnexionAction($c->get('view'), $c->get('logger'), $c->get('em'), $c->get('settings'));
};
// =============================================================
......
......@@ -13,16 +13,10 @@
// DIC configuration
$container = $app->getContainer();
// Error Handler
// $container['errorHandler'] = function ($c) {
// return new App\Action\CustomHandler($c->get('view'), $c->get('logger'));
// };
// Twig
$container['view'] = function ($c) {
$settings = $c->get('settings');
$view = new Slim\Views\Twig($settings['view']['template_path'], $settings['view']['twig']);
$view = new Slim\Views\Twig(__DIR__ . '/templates', $settings['view']['twig']);
// Add extensions
$view->addExtension(new Slim\Views\TwigExtension($c->get('router'), $c->get('request')->getUri()));
$view->addExtension(new Twig_Extension_Debug());
......@@ -34,17 +28,16 @@ $container['em'] = function ($c) {
$settings = $c->get('settings');
$metadata = $settings['database'];
$c = \Doctrine\ORM\Tools\Setup::createAnnotationMetadataConfiguration(
$metadata['entity_path'],
array('app/src/Entity'),
$metadata['dev_mode']
);
$c->setProxyDir(getcwd() . '/' . $metadata['path_proxy']);
$c->setProxyDir($metadata['path_proxy']);
if ($metadata['dev_mode']) {
$c->setAutoGenerateProxyClasses(true);
} else {
$c->setAutoGenerateProxyClasses(false);
}
$em = \Doctrine\ORM\EntityManager::create($metadata['connection_options'], $c);
return $em;
return \Doctrine\ORM\EntityManager::create($metadata['connection_options'], $c);
};
// monolog
......@@ -60,8 +53,7 @@ $container['logger'] = function ($c) {
$container['mailer'] = function ($c) {
$settings = $c->get('settings');
$transport = \Swift_SmtpTransport::newInstance($settings['mailer']['host'], $settings['mailer']['port']);
$mailer = \Swift_Mailer::newInstance($transport);
return $mailer;
return \Swift_Mailer::newInstance($transport);
};
// -----------------------------------------------------------------------------
......@@ -69,10 +61,9 @@ $container['mailer'] = function ($c) {
// -----------------------------------------------------------------------------
$container['App\Middleware\TokenMiddleware'] = function ($c) {
return new App\Middleware\TokenMiddleware($c->get('logger'));
return new App\Middleware\TokenMiddleware($c->get('logger'), $c->get('settings'));
};
$container['App\Middleware\DatabaseAccessMiddleware'] = function ($c) {
return new App\Middleware\DatabaseAccessMiddleware($c->get('logger'), $c->get('em'));
};
<?php
// Application middleware
// e.g: $app->add(new \Slim\Csrf\Guard);
//$app->add(App\Middleware\DatabaseAccessMiddleware::class);
......@@ -14,50 +14,57 @@ return [
'settings' => [
// Slim Settings
'determineRouteBeforeAppMiddleware' => false,
'displayErrorDetails' => true,
'displayErrorDetails' => getenv('SLIM_DISPLAY_ERROR_DETAILS'),
// View settings
'view' => [
'template_path' => __DIR__ . '/templates',
'twig' => [
'cache' => __DIR__ . '/../cache/twig',
'debug' => true,
'auto_reload' => true,
'cache' => getenv('TWIG_CACHE'),
'debug' => getenv('TWIG_DEBUG'),
'auto_reload' => getenv('TWIG_AUTO_RELOAD'),
],
],
// monolog settings
'logger' => [
'name' => 'app',
'path' => __DIR__ . '/../log/app.log',
'name' => getenv('LOGGER_NAME'),
'path' => getenv('LOGGER_PATH'),
],
// database settings (doctrine 2)
'database' => [
'entity_path' => ['app/src/Entity'],
'path_proxy' => 'cache/doctrine_proxy',
'dev_mode' => true,
'connection_options' => [
'driver' => 'pdo_pgsql',
'host' => 'cesamsidb',
'user' => 'jdev',
'password' => 'jdev2017',
'dbname' => 'jdevdb' // jdevdb (dev), jdev2017 (prod)
]
],
'database' => [
'path_proxy' => getenv('DOCTRINE_PATH_PROXY'),
'dev_mode' => getenv('DOCTRINE_DEV_MODE'),
'connection_options' => [
'driver' => getenv('DB_DRIVER'),
'host' => getenv('DB_HOST'), // cesamsidb (@LAM), db (@local)
'user' => getenv('DB_USER'),
'password' => getenv('DB_PASSWORD'),
'dbname' => getenv('DB_DBNAME') // jdevdb (dev), jdev2017 (prod)
]
],
'mailer' => [
'host' => 'smtp.osupytheas.fr', //localhost (dev), smtp.osupytheas.fr (prod)
'port' => 1025 // 1025 (dev), 25 (prod)
'host' => getenv('MAILER_HOST'), //localhost (dev), smtp.osupytheas.fr (prod)
'port' => getenv('MAILER_PORT') // 1025 (dev), 25 (prod)
],
// JDEV settings
'jdev' => [
'label' => 'JDEV2017',
'url' => 'jdev2017.fr',
'email' => 'chrystel.moreau@lam.fr', // jdev2017-inscription@univ-amu.fr (prod)
'email_clo' => 'jdev2017-co@univ-amu.fr',
'email_sponsor' => 'jdev2017-sponsor@univ-amu.fr',
'email_programme' => 'jdev2017-programme@univ-amu.fr',
'email_info' => 'jdev2017@univ-amu.fr',
'date_debut' => '2017-07-04', //'04/07/2017',
'date_fin' => '2017-07-07', //'07/07/2017',
'j1' => '2017-07-04',
'j2' => '2017-07-05',
'j3' => '2017-07-06',
'j1' => '2017-07-04',
'j2' => '2017-07-05',
'j3' => '2017-07-06',
'j4' => '2017-07-07',
'version' => 3, // 1 version de base, 2 version avec le sondage actif, 3 version avec le parcours actif , 4 version durant les JDEVs, 5 apres les JDEVs
// 1 version de base
// 2 version avec le sondage actif
// 3 version avec le parcours actif
// 4 version durant les JDEVs
// 5 apres les JDEVs
'version' => 3
]
]
];
......@@ -24,7 +24,7 @@ final class AdminValidPaiementAction
private $em;
private $mailer;
private $settings;
public function __construct(Twig $view, LoggerInterface $logger, EntityManagerInterface $em, $mailer, $settings)
{
$this->view = $view;
......@@ -33,7 +33,7 @@ final class AdminValidPaiementAction
$this->mailer = $mailer;
$this->settings = $settings;
}
public function __invoke(Request $request, Response $response, $args)
{
$this->logger->info("admin valid paiement page action dispatched");
......@@ -44,7 +44,7 @@ final class AdminValidPaiementAction
$roleSI = $request->getAttribute('roleSI');
if ( ($roleSI != 'admin') && ($roleSI != 'clo_admin') ) {
if (($roleSI != 'admin') && ($roleSI != 'clo_admin')) {
return $response->withStatus(401);
}
......@@ -61,46 +61,40 @@ final class AdminValidPaiementAction
// Si invalidation d'une place pre-payée
if ($valid == 'false') {
$organisme = $this->getOrganisme($participant->getOrganisme()->getId());
$participant->setAccesValide(false);
$participant->setPassPrepaye(false);
$organisme->setNbLibres($organisme->getNbLibres() + 1);
$this->em->flush();
$this->sendEmailInvalidation($participant);
return $response;
}
// Si validation du paiment Azur-Colloque
else {
} else {
// Si validation du paiment Azur-Colloque
$participant->setAccesValide(true);
$this->em->flush();
$this->sendEmailPaiement($participant);
return $response;
}
}
}
private function getParticipant($email)
{
$participant = $this->em->getRepository('App\Entity\Participant')->findOneBy(array('email' => strtolower($email)));
if(isset($participant)) {
if (isset($participant)) {
return $participant;
} else {
return true;
}
}
private function getOrganisme($orga_id)
{
$organisme = $this->em->getRepository('App\Entity\Organisme')->findOneBy(array('id' => $orga_id));
if(isset($organisme)) {
if (isset($organisme)) {
return $organisme;
} else {
return true;
}
}
private function sendEmailInvalidation($participant)
{
......@@ -114,7 +108,7 @@ final class AdminValidPaiementAction
$body .= 'Bien cordialement' . PHP_EOL;
$body .= 'Le comité d\'organisation des ' . $this->settings['jdev']['label'];
$message = \Swift_Message::newInstance('Invalidation place pré-payée '. $this->settings['jdev']['label'])
$message = \Swift_Message::newInstance('Invalidation place pré-payée ' . $this->settings['jdev']['label'])
->setFrom(['noreply@' . $this->settings['jdev']['url'] => $this->settings['jdev']['url']])
->setTo([$participant->getEmail(), $this->settings['jdev']['email']])
->setBody($body);
......
......@@ -19,54 +19,54 @@ use Psr\Http\Message\ResponseInterface as Response;
final class AdminValidRoleAction
{
private $view;
private $logger;
private $em;
private $view;
private $logger;
private $em;
private $mailer;
private $settings;
public function __construct(Twig $view, LoggerInterface $logger, EntityManagerInterface $em, $mailer, $settings)
{
$this->view = $view;
$this->logger = $logger;
$this->em = $em;
$this->mailer = $mailer;
$this->settings = $settings;
}
public function __invoke(Request $request, Response $response, $args)
{
$this->logger->info("admin valid role page action dispatched");
$params = $request->getQueryParams();
$token = $params['token'];
$roleSI = $request->getAttribute('roleSI');
public function __construct(Twig $view, LoggerInterface $logger, EntityManagerInterface $em, $mailer, $settings)
{
$this->view = $view;
$this->logger = $logger;
$this->em = $em;
$this->mailer = $mailer;
$this->settings = $settings;
}
if ($roleSI != 'admin') {
return $response->withStatus(401);
}
public function __invoke(Request $request, Response $response, $args)
{
$this->logger->info("admin valid role page action dispatched");
if (!array_key_exists('email', $params)) {
return $response->withStatus(400);
}
$participant = $this->getParticipant($params['email']);
if (!$participant) {
return $response->withStatus(400);
}
$params = $request->getQueryParams();
$token = $params['token'];
$roleSI = $request->getAttribute('roleSI');
if ($roleSI != 'admin') {
return $response->withStatus(401);
}
if (!array_key_exists('email', $params)) {
return $response->withStatus(400);
}
$participant = $this->getParticipant($params['email']);
if (!$participant) {
return $response->withStatus(400);
}
$participant->setCloValide(true);
$participant->setAccesValide(true);
$this->em->flush();
$this->sendEmail($participant);
return $response;
$participant->setCloValide(true);
$participant->setAccesValide(true);
$this->em->flush();
$this->sendEmail($participant);
return $response;
}
private function getParticipant($email)
{
$participant = $this->em->getRepository('App\Entity\Participant')->findOneBy(array('email' => strtolower($email)));
if(isset($participant)) {
if (isset($participant)) {
return $participant;
} else {
return false;
......
......@@ -19,59 +19,58 @@ use Psr\Http\Message\ResponseInterface as Response;
final class ChangePasswdAction
{
private $view;
private $logger;
private $view;
private $logger;
private $em;
private $mailer;
private $settings;
public function __construct(Twig $view, LoggerInterface $logger, EntityManagerInterface $em, $mailer, $settings)
{
$this->view = $view;
$this->logger = $logger;
public function __construct(Twig $view, LoggerInterface $logger, EntityManagerInterface $em, $mailer, $settings)
{
$this->view = $view;
$this->logger = $logger;
$this->mailer = $mailer;
$this->em = $em;
$this->settings = $settings;
}
public function __invoke(Request $request, Response $response, $args)
}
public function __invoke(Request $request, Response $response, $args)
{
$this->logger->info("Change Password page action dispatched");
if($request->isGet()) {
if ($request->isGet()) {
$this->view->render($response, 'change_passwd.twig', [
'page' => 'change-passwd'
]);
'page' => 'change-passwd'
]);
}
if($request->isPost()) {
$parsedBody = $request->getParsedBody();
if ($request->isPost()) {
$parsedBody = $request->getParsedBody();
$error = false;
$code = 200;
$messages = array();
if ($this->isEmptyField('email', $parsedBody)) {
$error = true;
$code = 400;
$messages[] = 'Champ email vide';
}
if ($this->isEmptyField('email', $parsedBody)) {
$error = true;
$code = 400;
$messages[] = 'Champ email vide';
}
if ($this->isEmptyField('apassword', $parsedBody)) {
$error = true;
$code = 400;
$messages[] = 'Champ ancien password vide';
}
$error = true;
$code = 400;
$messages[] = 'Champ ancien password vide';
}
if ($this->isEmptyField('npassword', $parsedBody)) {
$error = true;
$code = 400;
$messages[] = 'Champ nouveau password vide';
}
$error = true;
$code = 400;
$messages[] = 'Champ nouveau password vide';
}
$participant = $this->getParticipant($parsedBody);
if (!$participant)
{
if (!$participant) {
$error = true;
$code = 400;
$messages[] = 'L\'adresse email ne correspond à aucun participant';
......@@ -83,7 +82,7 @@ final class ChangePasswdAction
}
}
if ($error) {
if ($error) {
$response = $response->write(implode('<br>', $messages))->withStatus($code);
} else {
$participant->setPassword(password_hash($parsedBody['npassword'], PASSWORD_DEFAULT));
......@@ -93,14 +92,13 @@ final class ChangePasswdAction
$response = $response->write(json_encode(array('ok')))->withStatus($code);
}
}
}
return $response;
}
private function isEmptyField($field, $parsedBody)
private function isEmptyField($field, $parsedBody)
{
if(!isset($parsedBody[$field]) || empty($parsedBody[$field])) {
if (!isset($parsedBody[$field]) || empty($parsedBody[$field])) {
return true;
} else {