Commit 7e96a44b authored by okhin's avatar okhin 🚴

Merge branch 'preprod' into 'master'

Mise en production

See merge request !37
parents 0185770e d131a2fc
/nbproject/private/
*~
messages.pot
locales/es_ES/LC_MESSAGES/messages.mo
locales/de_DE/LC_MESSAGES/messages.mo
locales/en_US/LC_MESSAGES/messages.mo
locales/fr_FR/LC_MESSAGES/messages.mo
locales/it_IT/LC_MESSAGES/messages.mo
/.tx/
#images/logo-lqdn-2.png
static/images/logo-lqdn.png
images/ids/
images/logo-[0-9]*.png
images/banner1.png
images/banner_fr_FR.png
images/banner_en_US.png
videos/
admin/.htaccess
admin/.htpasswd
*.mo
pplome.*
*.log
tmp/*
admin/tmp/*
piplomes/
CACHE/
vendor/
pdf/
/phinx.yml
/app/env
app/env
.php_cs.cache
.DS_Store
__MAC
tests/_output/*
/var/log/*
!/var/log/.gitkeep
/.php_cs.cache
tests/*/_generated/*
tests/_data
tests/_output
tests/_support/_generated
......@@ -9,6 +9,7 @@ stages:
job test:
stage: test
variables:
GIT_SUBMODULE_STRATEGY: normal
SQL_HOST: "localhost"
SQL_PORT: "3306"
SQL_DATABASE: "test_$CI_BUILD_REF"
......@@ -44,7 +45,7 @@ job test:
- echo "SQL_DATABASE=${SQL_DATABASE}" >> app/env
- make install
- make server-start
- make test
- make -k test
- make server-stop
- mysql -u $SQL_USER -p$SQL_PASSWORD -e "DROP DATABASE $SQL_DATABASE"
tags:
......
[submodule "www/static/pi-billion"]
path = www/static/pi-billion
url = https://git.laquadrature.net/lqdn-interne/pi-billion.git
......@@ -31,10 +31,16 @@ doctor: ## Check that everything is installed to use this application
@which msgfmt >/dev/null 2>&1 && echo "\033[32mmsgfmt installed\033[0m" || echo "\033[31mmsgfmt not installed\033[0m"
@which xgettext >/dev/null 2>&1 && echo "\033[32mxgettext installed\033[0m" || echo "\033[31mxgettext not installed\033[0m"
@which pdftk >/dev/null 2>&1 && echo "\033[32mpdftk installed\033[0m" || echo "\033[31mpdftk not installed\033[0m"
@test -s /usr/share/php7.0-xml/xml/dom.ini && echo "\033[032mphp-ext-dom installed\033[0m" || echo "\033[31mphp-ext-dom not installed (php-xml)\033[0m"
@test -s /usr/share/php7.0-zip/zip/zip.ini && echo "\033[032mphp-zip installed\033[0m" || echo "\033[31mphp-zip not installed\033[0m"
@test -s /usr/share/php7.0-mbstring/mbstring/mbstring.ini && echo "\033[032mphp-mbstring installed\033[0m" || echo "\033[31mphp-mbstring not installed\033[0m"
@test -s /usr/share/php7.0-curl/curl/curl.ini && echo "\033[032mphp-curl installed\033[0m" || echo "\033[31mphp-curl not installed\033[0m"
install: ## Install the application
@echo "\033[1m\033[36m==> Install Composer dependencies\033[0m\033[21m"
@composer -n install
@mkdir -p ./log
@mkdir -p ./tmp
reset-db: ## Install or re-install the DB
@echo "\033[1m\033[36m==> Drop database "$(SQL_DATABASE)" if it already exists\033[0m\033[21m"
......@@ -56,12 +62,16 @@ test-functional: ## Launch functional tests.
@$(MAKE) reset-db
@./vendor/bin/codecept run functional
coverage: ## Launch functional tests with coverage.
@$(MAKE) reset-db
@./vendor/bin/codecept run functional --coverage-html
server-start: server-stop ## Launch a local server
@php -S 127.0.0.1:8000 >> ./var/log/server.log &
@php -S 127.0.0.1:8000 -t ./www/ >> ./log/server.log &
@echo "\033[32mServer running. (http://127.0.0.1:8000)\033[0m"
server-stop: ## Stop local server if running
@ps -aux | grep "[p]hp -S 127.0.0.1:8000" | grep -v grep | awk '{print $$2}' | xargs -r -n 1 kill
-@ps -aux | grep "[p]hp -S 127.0.0.1:8000" | grep -v grep | awk '{print $$2}' | xargs -r -n 1 kill
@echo "\033[32mServer stopped. (http://127.0.0.1:8000)\033[0m"
cs-fix: ## Fix CS
......
# LQDN soutien
## Installation
This is a php application based on Fat-Free-Framework and a MySQL database that handles donations and presents offered to donors to La Quadrature du Net
It's used as our primary donation platform, and uses our bank's payment system (cheaper) to get one-time or recurring payments recorded into the donation platform.
## Installation (quick)
In order to install this project, run `make doctor` to check that everything is fine.
......@@ -19,3 +23,52 @@ To access to the admin (`/admin`) use `admin`/`password`
## Contributing
Before submitting a PR, makes sure tests are OK: `make test`
# Detailed dependencies, installation ...
## Dependencies
This software depends on a few software :
* **composer** (to install php dependencies) see https://getcomposer.org/
* a **mysql client** (to inject the database schema)
* a **mysql server** (no need for it to be local)
* **pdftk** to generate pi-plomes (pdf with pi's decimals offered to our donors)
* **texlive-latex-base** for the `pdflatex` binary for the piplomes (only required in production or for people debugging the piplomes code)
and for developers you may also need :
* **xgettext** to manage translations, use:
* `make messages.pot` to update PO files from source code.
* `make translations` to compile MO files from PO files when translations are ready.
This software uses:
* **PHP5.6** currently (migration to PHP7.x is in the pipe)
* **phinx** to inject database schema and initial data / accounts into MySQL see https://phinx.org/
* **php-cs-fixer** to check php code for errors and fix coding standard issues, see https://github.com/FriendsOfPHP/PHP-CS-Fixer
* **doctrine/dbal** as ORM see https://github.com/doctrine/dbal
* **f3 framework** as main view / controller framework. see https://fatfreeframework.com/
Look at `app/` folder for most Controllers, and `app/routes.ini` for the application routes (the URLs)
# Production deployment (not finished)
* `app/env` must contains the proper values : database connection, bank visa payment codes, and ENV=production at the bottom.
* point your Nginx or Apache with PHP5.6 to the `www/` folder, and either allow Rewrite Rules (a2enmod rewrite) or point every URL not being a file to index.php (see below for an nginx sample)
* use AND FORCE https usage, it's 2018, people ;)
Nginx configuration sample:
```
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass unix:/run/php5.sock;
}
location / {
# try to serve file directly, fallback to index.php
try_files $uri /index.php$is_args$args;
}
```
......@@ -19,9 +19,9 @@ Cette fonction définit un mot de passe de 12 caractères
}
/*
Cette fonction cherche à nettoyer un mauvais encodage en utf-8.
*/
/*
Cette fonction cherche à nettoyer un mauvais encodage en utf-8.
*/
public static function clean_encoding($string)
{
$bad_encoding = array("é","à ","è","ç","ë","ô","î","ù");
......
[globals]
; Répertoire contenant les classes chargées dynamiquement
AUTOLOAD=app/
AUTOLOAD=../app/
; Répertoire contenant les templates
UI=templates/
UI=../app/view/
; Répertoire des fichiers temporaires
TEMP=../tmp/
; Répertoire des logs
LOGS=tmp
LOGS=../log/
; Gestionnaire d'erreur personnalisé
; ONERROR="Main->error"
......
......@@ -46,6 +46,14 @@ define("SMTP_PW", getenv('SMTP_PW'));
define("DEBUG", getenv('DEBUG'));
define("SENTRY", getenv('SENTRY'));
$sentry_client = new Raven_Client($SENTRY);
$error_handler = new Raven_ErrorHandler($sentry_client);
$error_handler->registerExceptionHandler();
$error_handler->registerErrorHandler();
$error_handler->registerShutdownFunction();
if ('prod' !== $env) {
error_reporting(E_ALL|E_WARNING);
ini_set("display_errors", true);
......
<?php
namespace Controller;
use LQDN\Command\AdminCreateCommand;
use LQDN\Command\AdminDeleteCommand;
......@@ -56,7 +57,7 @@ class Admin extends Controller
if (!$f3->get('SESSION.admin')) {
$mapper = new\DB\SQL\Mapper($f3->get('DB'), 'admins');
$auth = new \Auth($mapper, array('id'=>'user_id', 'pw'=>'password'));
$success = $auth->basic('Admin::hash_password');
$success = $auth->basic('\Controller\Admin::hash_password');
if (!$success) {
$f3->error(401);
} else {
......@@ -72,14 +73,6 @@ class Admin extends Controller
return hash('sha256', $password);
}
// Fonction appelée après routage
public function afterRoute($f3, $args)
{
// Rendu HTML de la page
parent::afterRoute($f3, $args);
echo Template::instance()->render('backend/base.html');
}
public function show($f3, $args)
{
if ($f3->get('VERB')=='POST' && $f3->exists('POST.action')) {
......@@ -155,10 +148,10 @@ class Admin extends Controller
// We need to check if there's already a user with this email
$result = $db->query("SELECT id
FROM users
WHERE email='".Utils::asl($email)."'");
WHERE email='".\Utils::asl($email)."'");
if ($result) {
// The user already exist, lets get the user_id
$user_id = $result->fetch(PDO::FETCH_ASSOC);
$user_id = $result->fetch(\PDO::FETCH_ASSOC);
$user_id = $user_id['id'];
} else {
// Let's create the account first
......@@ -167,9 +160,9 @@ class Admin extends Controller
pseudo,
cumul,
total)
VALUES('".Utils::asl($email)."',
'".Utils::asl($pseudo)."',
'".Utils::asl($somme)."',
VALUES('".\Utils::asl($email)."',
'".\Utils::asl($pseudo)."',
'".\Utils::asl($somme)."',
'0')");
$user_id = $db->lastInsertId();
}
......@@ -183,11 +176,11 @@ class Admin extends Controller
status)
VALUES
(now(),
'".Utils::asl($user_id)."',
'".Utils::asl($somme)."',
'".Utils::asl($lang)."',
'".Utils::asl($abo)."',
'".Utils::asl($public)."',
'".\Utils::asl($user_id)."',
'".\Utils::asl($somme)."',
'".\Utils::asl($lang)."',
'".\Utils::asl($abo)."',
'".\Utils::asl($public)."',
1)");
// Récupération de l'id pour passage en mode édition
$id = $db->lastInsertId();
......@@ -201,40 +194,40 @@ class Admin extends Controller
$result = $db->query("SELECT adresse_id,
user_id
FROM dons
WHERE id = ".Utils::asl($f3->get('POST.id')));
$result = $result->fetch(PDO::FETCH_ASSOC);
WHERE id = ".\Utils::asl($f3->get('POST.id')));
$result = $result->fetch(\PDO::FETCH_ASSOC);
// Let's update the adresse first or create the adress
if ($result['adresse_id'] == '0') {
$db->query("INSERT INTO adresses
(nom, adresse, adresse2, codepostal, ville, pays)
VALUES ('".Utils::asl($nom)."',
'".Utils::asl($adresse)."',
'".Utils::asl($adresse2)."',
'".Utils::asl($codepostal)."',
'".Utils::asl($ville)."',
'".Utils::asl($pays)."')");
VALUES ('".\Utils::asl($nom)."',
'".\Utils::asl($adresse)."',
'".\Utils::asl($adresse2)."',
'".\Utils::asl($codepostal)."',
'".\Utils::asl($ville)."',
'".\Utils::asl($pays)."')");
$result['adresse_id'] = $db->lastInsertId();
} else {
$db->query("UPDATE adresses
SET nom='".Utils::asl($nom)."',
adresse='".Utils::asl($adresse)."',
adresse2='".Utils::asl($adresse2)."',
codepostal='".Utils::asl($codepostal)."',
ville='".Utils::asl($ville)."',
pays='".Utils::asl($pays)."'
SET nom='".\Utils::asl($nom)."',
adresse='".\Utils::asl($adresse)."',
adresse2='".\Utils::asl($adresse2)."',
codepostal='".\Utils::asl($codepostal)."',
ville='".\Utils::asl($ville)."',
pays='".\Utils::asl($pays)."'
WHERE id={$result['adresse_id']}");
}
$db->query("UPDATE users
SET email='".Utils::asl($email)."',
pseudo='".Utils::asl($pseudo)."'
SET email='".\Utils::asl($email)."',
pseudo='".\Utils::asl($pseudo)."'
WHERE id={$result['user_id']}");
$db->query("UPDATE dons
SET somme='".Utils::asl($somme)."',
lang='".Utils::asl($lang)."',
abo='".Utils::asl($abo)."',
public='".Utils::asl($public)."',
SET somme='".\Utils::asl($somme)."',
lang='".\Utils::asl($lang)."',
abo='".\Utils::asl($abo)."',
public='".\Utils::asl($public)."',
adresse_id='".$result['adresse_id']."'
WHERE id='".Utils::asl($_POST['id'])."'");
WHERE id='".\Utils::asl($_POST['id'])."'");
}
}
}
......@@ -253,7 +246,7 @@ class Admin extends Controller
FROM dons d
JOIN users u ON u.id = d.user_id
WHERE d.id=".$id);
$don = $result->fetch(PDO::FETCH_ASSOC);
$don = $result->fetch(\PDO::FETCH_ASSOC);
} else {
$don = array(
'id'=>$id,
......@@ -281,7 +274,7 @@ class Admin extends Controller
$query = "SELECT DISTINCT quoi FROM contreparties;";
$result = $db->query($query);
if ($result) {
foreach ($result->fetchAll(PDO::FETCH_ASSOC) as $row) {
foreach ($result->fetchAll(\PDO::FETCH_ASSOC) as $row) {
$f3->set($row['quoi'].'_s1', 0);
$f3->set($row['quoi'].'_s2', 0);
}
......@@ -294,7 +287,7 @@ class Admin extends Controller
GROUP BY quoi, status;";
$result = $db->query($query);
if ($result) {
foreach ($result->fetchAll(PDO::FETCH_ASSOC) as $row) {
foreach ($result->fetchAll(\PDO::FETCH_ASSOC) as $row) {
$f3->set($row['quoi'].'_s'.$row['status'], $row['qte']);
}
}
......@@ -310,7 +303,7 @@ class Admin extends Controller
GROUP BY quoi, taille;";
$result = $db->query($query);
if ($result) {
foreach ($result->fetchAll(PDO::FETCH_ASSOC) as $row) {
foreach ($result->fetchAll(\PDO::FETCH_ASSOC) as $row) {
$f3->set($row['quoi'].'_t'.$row['taille'], $row['qte']);
}
}
......@@ -400,16 +393,16 @@ class Admin extends Controller
case 0:
break;
case 1:
$query .= " AND c.quoi='".Utils::asl('pibag')."' ";
$query .= " AND c.quoi='".\Utils::asl('pibag')."' ";
break;
case 2:
$query .= " AND c.quoi='".Utils::asl('piplome')."' ";
$query .= " AND c.quoi='".\Utils::asl('piplome')."' ";
break;
case 4:
$query .= " AND c.quoi='".Utils::asl('pishirt')."' ";
$query .= " AND c.quoi='".\Utils::asl('pishirt')."' ";
break;
case 8:
$query .= " AND c.quoi='".Utils::asl('hoodie')."' ";
$query .= " AND c.quoi='".\Utils::asl('hoodie')."' ";
break;
default:
$query .= " AND datec IN (
......@@ -428,14 +421,14 @@ class Admin extends Controller
";
}
if ($status) {
$query .= " AND c.status IN (".Utils::asl($status).") ";
$query .= " AND c.status IN (".\Utils::asl($status).") ";
}
$query .= " ORDER BY c.datec DESC LIMIT 0,".$limite.";";
$result = $db->query($query);
$data = array();
if ($result) {
$i = 0;
foreach ($result->fetchAll(PDO::FETCH_ASSOC) as $row) {
foreach ($result->fetchAll(\PDO::FETCH_ASSOC) as $row) {
if ($row['quoi']=='piplome') {
$pdf = $db->query("SELECT d.id AS id,
a.nom AS pseudo,
......@@ -444,7 +437,7 @@ class Admin extends Controller
JOIN adresses a ON a.id = d.adresse_id
WHERE d.id='".$row['taille']."'");
if ($pdf) {
$pdf = $pdf->fetch(PDO::FETCH_ASSOC);
$pdf = $pdf->fetch(\PDO::FETCH_ASSOC);
}
$row['pdf_id'] = $pdf['id'];
$row['pdf_nom'] = $pdf['pseudo'];
......@@ -489,25 +482,25 @@ class Admin extends Controller
$row['taille'] = "N/A";
}
$row['count'] = $count++;
$row['email'] = Utils::clean_encoding($row['email']);
$row['pseudo'] = Utils::clean_encoding($row['pseudo']);
$row['nom'] = Utils::clean_encoding($row['nom']);
$adresse = Utils::clean_encoding($row['adresse']);
$row['email'] = \Utils::clean_encoding($row['email']);
$row['pseudo'] = \Utils::clean_encoding($row['pseudo']);
$row['nom'] = \Utils::clean_encoding($row['nom']);
$adresse = \Utils::clean_encoding($row['adresse']);
$adresse = preg_replace('/\n|\r/', ' ', $adresse);
$adresse = preg_replace('/^'.$row['nom'].'/', '', $adresse);
$row['adresse'] = $adresse;
$adresse2 = Utils::clean_encoding($row['adresse2']);
$adresse2 = \Utils::clean_encoding($row['adresse2']);
$adresse2 = preg_replace('/\n|\r/', ' ', $adresse2);
$adresse2 = preg_replace('/^'.$row['nom'].'/', '', $adresse2);
$row['adresse2'] = $adresse2;
$row['codepostal'] = Utils::clean_encoding($row['codepostal']);
$row['ville'] = Utils::clean_encoding($row['ville']);
$row['pays'] = Utils::clean_encoding($row['pays']);
$row['datec'] = Utils::clean_encoding($row['datec']);
$row['taille'] = Utils::clean_encoding($row['taille']);
$row['pdf_id'] = Utils::clean_encoding($row['pdf_id']);
$row['pdf_nom'] = Utils::clean_encoding($row['pdf_nom']);
$row['commentaire'] = Utils::clean_encoding($row['commentaire']);
$row['codepostal'] = \Utils::clean_encoding($row['codepostal']);
$row['ville'] = \Utils::clean_encoding($row['ville']);
$row['pays'] = \Utils::clean_encoding($row['pays']);
$row['datec'] = \Utils::clean_encoding($row['datec']);
$row['taille'] = \Utils::clean_encoding($row['taille']);
$row['pdf_id'] = \Utils::clean_encoding($row['pdf_id']);
$row['pdf_nom'] = \Utils::clean_encoding($row['pdf_nom']);
$row['commentaire'] = \Utils::clean_encoding($row['commentaire']);
$rows[] = $row;
}
$f3->set('headers', array(
......@@ -572,39 +565,39 @@ class Admin extends Controller
// First, let's retrieve the adresse from the adresse_id if it exists
$result = $db->query("SELECT adresse_id
FROM contreparties
WHERE id = '".Utils::asl($f3->get('POST.id'))."'
WHERE id = '".\Utils::asl($f3->get('POST.id'))."'
AND adresse_id IS NOT NULL");
$result = $result->fetch(PDO::FETCH_ASSOC);
$result = $result->fetch(\PDO::FETCH_ASSOC);
$adresse_id = $result['adresse_id'];
if (!$adresse_id or $adresse_id == 0) {
// We need to create an adresse_id
$db->query("INSERT INTO adresses
VALUES (nom='".Utils::asl($nom)."',
adresse='".Utils::asl($adresse)."',
adresse2='".Utils::asl($adresse2)."',
codepostal='".Utils::asl($codepostal)."',
ville='".Utils::asl($ville)."',
pays='".Utils::asl($pays)."')");
VALUES (nom='".\Utils::asl($nom)."',
adresse='".\Utils::asl($adresse)."',
adresse2='".\Utils::asl($adresse2)."',
codepostal='".\Utils::asl($codepostal)."',
ville='".\Utils::asl($ville)."',
pays='".\Utils::asl($pays)."')");
$adresse_id = $db->lastInsertId();
}
// Updating the adresses first
$db->query("UPDATE adresses
SET nom='".Utils::asl($nom)."',
adresse='".Utils::asl($adresse)."',
adresse2='".Utils::asl($adresse2)."',
codepostal='".Utils::asl($codepostal)."',
ville='".Utils::asl($ville)."',
pays='".Utils::asl($pays)."'
SET nom='".\Utils::asl($nom)."',
adresse='".\Utils::asl($adresse)."',
adresse2='".\Utils::asl($adresse2)."',
codepostal='".\Utils::asl($codepostal)."',
ville='".\Utils::asl($ville)."',
pays='".\Utils::asl($pays)."'
WHERE id = $adresse_id");
$db->query("UPDATE contreparties
SET quoi='".Utils::asl($quoi)."',
taille='".Utils::asl($taille)."',
status='".Utils::asl($status)."'
WHERE id='".Utils::asl($_POST['id'])."'");