From bf1b454efada4201bf428e317f2f70135ee66397 Mon Sep 17 00:00:00 2001
From: Phyks
Date: Fri, 6 Sep 2013 20:07:28 +0200
Subject: [PATCH] Started to write the code to handle json API
---
TODO | 3 +-
inc/Storage.class.php | 2 +-
inc/User.class.php | 23 +++++++--
inc/functions.php | 2 +-
index.php | 91 ++++++++++++++++++++++++++--------
tpl/default_en/edit_users.html | 9 ++++
tpl/json/connection.html | 5 ++
tpl/json/edit_users.html | 62 +++++++++++++++++++++++
tpl/json/index.html | 54 ++++++++++++++++++++
tpl/json/new_invoice.html | 52 +++++++++++++++++++
tpl/json/settings.html | 63 +++++++++++++++++++++++
11 files changed, 338 insertions(+), 28 deletions(-)
create mode 100644 tpl/json/connection.html
create mode 100644 tpl/json/edit_users.html
create mode 100755 tpl/json/index.html
create mode 100755 tpl/json/new_invoice.html
create mode 100644 tpl/json/settings.html
diff --git a/TODO b/TODO
index 8c22d70..5a32992 100755
--- a/TODO
+++ b/TODO
@@ -1,5 +1,5 @@
* Don't cache the username
-* JSON output
+* JSON output => do the template
inc/Invoices.class.php :
========================
@@ -9,6 +9,7 @@ inc/Invoices.class.php :
Manage paybacks :
=================
* TODO : Payback system (class should be ok)
+* TODO : Global payback
To test :
=========
diff --git a/inc/Storage.class.php b/inc/Storage.class.php
index adeb72d..e3c87f6 100644
--- a/inc/Storage.class.php
+++ b/inc/Storage.class.php
@@ -228,7 +228,7 @@ class Storage {
foreach($this->fields as $field=>$type) {
if(isset($this->$field)) {
- if($fields[$field] == 'date')
+ if($type == 'date')
$value = $value->format('Y-m-d H:i:s');
$query->bindParam(':'.$field, $this->$field);
diff --git a/inc/User.class.php b/inc/User.class.php
index 3a2f38d..ce1fb5c 100644
--- a/inc/User.class.php
+++ b/inc/User.class.php
@@ -3,14 +3,15 @@ require_once('data/config.php');
require_once('Storage.class.php');
class User extends Storage {
- protected $id = 0, $login, $display_name, $password, $admin;
+ protected $id = 0, $login, $display_name, $password, $admin, $json_token;
protected $TABLE_NAME = "Users";
protected $fields = array(
'id'=>'key',
'login'=>'string',
'display_name'=>'string',
'password'=>'password',
- 'admin'=>'bool'
+ 'admin'=>'bool',
+ 'json_token'=>'string',
);
public function __construct() {
@@ -35,6 +36,10 @@ class User extends Storage {
return $this->admin;
}
+ public function getJsonToken() {
+ return $this->json_token;
+ }
+
// Setters
// =======
public function setId($id) {
@@ -57,6 +62,10 @@ class User extends Storage {
$this->admin = (bool) $admin;
}
+ public function setJsonToken($token) {
+ $this->json_token = $token;
+ }
+
// Password functions
// ==================
public function encrypt($text) {
@@ -67,6 +76,12 @@ class User extends Storage {
return User::encrypt($password) == $this->password;
}
+ // JSON token functions
+ // ====================
+ public function newJsonToken() {
+ $this->json_token = md5(uniqid(mt_rand(), true));
+ }
+
// Check if a user exists by login and load it
// ===========================================
public function exists() {
@@ -83,7 +98,7 @@ class User extends Storage {
// Session storage
// ===============
public function sessionStore() {
- return serialize(array('id'=>$this->id, 'login'=>$this->login, 'display_name'=>$this->display_name, 'password'=>$this->password, 'admin'=>$this->admin));
+ return serialize(array('id'=>$this->id, 'login'=>$this->login, 'display_name'=>$this->display_name, 'password'=>$this->password, 'admin'=>$this->admin, 'json_token'=>$this->json_token));
}
public function sessionRestore($data, $serialized = false) {
@@ -97,6 +112,7 @@ class User extends Storage {
$this->setDisplayName($user_data['display_name']);
$this->setPassword($user_data['password']);
$this->setAdmin($user_data['admin']);
+ $this->setJsonToken($user_data['json_token']);
}
// Check wether a user already exists or not
@@ -118,6 +134,7 @@ class User extends Storage {
$this->login = htmlspecialchars($this->login);
$this->display_name = htmlspecialchars($this->display_name);
$this->admin = (int) $this->admin;
+ $this->json_token = htmlspecialchars($this->json_token);
return $this;
}
diff --git a/inc/functions.php b/inc/functions.php
index 582b97e..2103edf 100644
--- a/inc/functions.php
+++ b/inc/functions.php
@@ -61,7 +61,7 @@
if ($handle = opendir($dir)) {
while (false !== ($entry = readdir($handle))) {
- if ($entry != "." && $entry != ".." && is_dir($dir.$entry)) {
+ if ($entry != "." && $entry != ".." && $entry != 'json' && is_dir($dir.$entry)) {
$return[] = array('value'=>$entry, 'option'=>str_replace(array('_en', '_fr'), array(' (English)', ' (French)'), $entry));
}
}
diff --git a/index.php b/index.php
index 1a05375..0fa4aa7 100644
--- a/index.php
+++ b/index.php
@@ -20,7 +20,14 @@
require_once('inc/functions.php');
require_once('inc/Ban.inc.php');
require_once('inc/CSRF.inc.php');
- raintpl::$tpl_dir = TEMPLATE_DIR;
+ if(!empty($_GET['json'])) {
+ raintpl::$tpl_dir = 'tpl/json/';
+ $get_redir = 'json=1';
+ }
+ else {
+ raintpl::$tpl_dir = TEMPLATE_DIR;
+ $get_redir = '';
+ }
raintpl::$cache_dir = 'tmp/';
// Define raintpl instance
@@ -57,17 +64,35 @@
}
$tpl->assign('current_user', secureDisplay($current_user));
- // If not connected, redirect to connection page
- if($current_user === false && (empty($_GET['do']) OR $_GET['do'] != 'connect')) {
- header('location: index.php?do=connect');
- exit();
+ if(!empty($_GET['json_token'])) {
+ $current_user = new User();
+
+ if($current_user->load(array('json_token'=>$_GET['json_token'], true)) === false) {
+ header('location: index.php?do=connect'.$get_redir);
+ exit();
+ }
+ else {
+ if(!empty($get_redir))
+ $get_redir .= '&';
+
+ $get_redir .= 'json_token='.$_GET['json_token'];
+ }
}
-
- // If IP has changed, logout
- if($current_user !== false && user_ip() != $_SESSION['ip']) {
- session_destroy();
- header('location: index.php?do=connect');
- exit();
+ else {
+ //If json token not available
+
+ // If not connected, redirect to connection page
+ if($current_user === false && (empty($_GET['do']) OR $_GET['do'] != 'connect')) {
+ header('location: index.php?do=connect&'.$get_redir);
+ exit();
+ }
+
+ // If IP has changed, logout
+ if($current_user !== false && user_ip() != $_SESSION['ip']) {
+ session_destroy();
+ header('location: index.php?do=connect&'.$get_redir);
+ exit();
+ }
}
// Initialize empty $_GET['do'] if required to avoid error
@@ -79,7 +104,7 @@
switch($_GET['do']) {
case 'connect':
if($current_user !== false) {
- header('location: index.php');
+ header('location: index.php?'.$get_redir);
exit();
}
if(!empty($_POST['login']) && !empty($_POST['password']) && check_token(600, 'connection')) {
@@ -106,7 +131,7 @@
session_set_cookie_params($_SESSION['remember_me'], $cookie_dir, $_SERVER['HTTP_HOST']);
session_regenerate_id(true);
- header('location: index.php');
+ header('location: index.php?'.$get_redir);
exit();
}
else {
@@ -124,7 +149,7 @@
case 'disconnect':
$current_user = false;
session_destroy();
- header('location: index.php?do=connect');
+ header('location: index.php?do=connect&'.$get_redir);
exit();
break;
@@ -135,7 +160,7 @@
$current_user->setPassword($current_user->encrypt($_POST['password']));
$current_user->save();
- header('location: index.php');
+ header('location: index.php?'.$get_redir);
exit();
}
else {
@@ -147,6 +172,7 @@
}
}
$tpl->assign('view', 'password');
+ $tpl->assign('json_token', htmlspecialchars($current_user->getJsonToken()));
$tpl->assign('token', generate_token('password'));
$tpl->draw('edit_users');
break;
@@ -154,7 +180,7 @@
case 'edit_users':
case 'add_user':
if(!$current_user->getAdmin()) {
- header('location: index.php');
+ header('location: index.php?'.$get_redir);
exit();
}
@@ -164,6 +190,9 @@
if(!empty($_POST['user_id'])) {
$user->setId($_POST['user_id']);
}
+ else {
+ $user->newJsonToken();
+ }
$user->setLogin($_POST['login']);
$user->setDisplayName($_POST['display_name']);
if(!empty($_POST['password'])) {
@@ -177,7 +206,7 @@
// Clear the cache
array_map("unlink", glob(raintpl::$cache_dir."*.rtpl.php"));
- header('location: index.php?do=edit_users');
+ header('location: index.php?do=edit_users&'.$get_redir);
exit();
}
else {
@@ -213,6 +242,24 @@
$tpl->draw('edit_users');
break;
+ case 'new_token':
+ if(!empty($_GET['user_id']) && $current_user->getAdmin()) {
+ $user_id = (int) $_GET['user_id'];
+ }
+ else {
+ $user_id = $current_user->getId();
+ }
+
+ $user = new User();
+ $user = $user->load(array('id'=>$user_id), true);
+ $user->newJsonToken();
+ $user->save();
+ $_SESSION['current_user'] = $user->sessionStore();
+
+ header('location: index.php'.$get_redir);
+ exit();
+ break;
+
case 'delete_user':
if($_GET['user_id'] != $current_user->getId()) {
$user = new User();
@@ -222,7 +269,7 @@
// Clear the cache
array_map("unlink", glob(raintpl::$cache_dir."*.rtpl.php"));
- header('location: index.php?do=edit_users');
+ header('location: index.php?do=edit_users&'.$get_redir);
exit();
}
break;
@@ -234,7 +281,7 @@
// Clear the cache
array_map("unlink", glob(raintpl::$cache_dir."*.rtpl.php"));
- header('location: index.php');
+ header('location: index.php?'.$get_redir);
exit();
}
@@ -286,7 +333,7 @@
// Clear the cache
array_map("unlink", glob(raintpl::$cache_dir."*.rtpl.php"));
- header('location: index.php');
+ header('location: index.php?'.$get_redir);
exit();
}
else {
@@ -366,7 +413,7 @@
// Clear the cache
array_map("unlink", glob(raintpl::$cache_dir."*.rtpl.php"));
- header('location: index.php');
+ header('location: index.php?'.$get_redir);
exit();
}
}
@@ -405,7 +452,7 @@
// Clear the cache
array_map("unlink", glob(raintpl::$cache_dir."*.rtpl.php"));
- header('location: index.php');
+ header('location: index.php?'.$get_redir);
exit();
}
break;
diff --git a/tpl/default_en/edit_users.html b/tpl/default_en/edit_users.html
index 1e85862..3f6aae5 100644
--- a/tpl/default_en/edit_users.html
+++ b/tpl/default_en/edit_users.html
@@ -54,6 +54,11 @@
+{if condition="$user_id != -1"}
+ Personal token for this user
+ The personal token for this user to be used with the API is : {$user_data->getJsonToken()}. If you think it might be compromised, you can generate a new one .
+{/if}
+
{elseif condition="$view == 'password'"}
Edit your password
+
+Your personal token to use the API
+Your personal token to use the API is : {$json_token}. If you think it might be compromised, you can generate a new one .
{/if}
+{include="footer"}
diff --git a/tpl/json/connection.html b/tpl/json/connection.html
new file mode 100644
index 0000000..e1ee7d6
--- /dev/null
+++ b/tpl/json/connection.html
@@ -0,0 +1,5 @@
+{if condition="LANG=='fr'"}
+ Vous devez utiliser votre token unique d'identification pour l'utilisation de l'API JSON. Vous pouvez le trouver dans le menu "Modifier votre mot de passe".
+{else}
+ You must use your unique id token to use JSON API. You can find it under the "Edit password" menu.
+{/if}
diff --git a/tpl/json/edit_users.html b/tpl/json/edit_users.html
new file mode 100644
index 0000000..cb9669c
--- /dev/null
+++ b/tpl/json/edit_users.html
@@ -0,0 +1,62 @@
+{if condition="$error != ''"}
+ {$error}
+{/if}
+
+{if condition="$view == 'list_users'"}
+List of users
+You can also add a user .
+
+
+ Id
+ Login
+ Display Name
+ Is admin ?
+ Edit
+ Delete
+
+ {loop="users"}
+
+ {$value->getId()}
+ {$value->getLogin()}
+ {$value->getDisplayName()}
+ {$value->getAdmin() ? "Yes" : "No"}
+ Edit
+ {if condition="$value->getId() != $current_user->getId()"}Delete {/if}
+
+ {/loop}
+
+{elseif condition="$view == 'edit_user'"}
+{$user_id != -1 ? 'Edit' : 'Add'} a user
+
+
+{elseif condition="$view == 'password'"}
+Edit your password
+
+{/if}
diff --git a/tpl/json/index.html b/tpl/json/index.html
new file mode 100755
index 0000000..cca8039
--- /dev/null
+++ b/tpl/json/index.html
@@ -0,0 +1,54 @@
+{if condition="$notice != ''"}
+
+{/if}
+
+
+
Balance
+
Read line owes case {$currency} to column . You can click on links to confirm the payback.
+
+
+ Owes\To
+ {loop="users"}
+ {$value->getDisplayName()}
+ {/loop}
+
+ {loop="users"}
+
+ {$value->getDisplayName()}
+ {loop="users"}
+ {$value->getDisplayName()}
+ {/loop}
+
+ {/loop}
+
+
+
+
Detailed list of bills for last month
+
+ {if condition="count($invoices)>1"}
+
+
+ Date
+ Paid by
+ Users in
+ Amount
+ What ?
+ Edit
+ Delete
+
+ {loop="invoices"}
+
+ {$value->getDate()}
+ {$value->getBuyer()->getDisplayName()}
+ {$value->getUsersIn()}
+ {$value->getAmount()}
+ {$value->getWhat()}
+ Edit
+ Delete
+
+ {/loop}
+
+ {else}
+
No bills added.
+ {/if}
+
diff --git a/tpl/json/new_invoice.html b/tpl/json/new_invoice.html
new file mode 100755
index 0000000..febe8f0
--- /dev/null
+++ b/tpl/json/new_invoice.html
@@ -0,0 +1,52 @@
+{if condition="$error != ''"}
+ {$error}
+{/if}
+
+Add a bill
+
+
diff --git a/tpl/json/settings.html b/tpl/json/settings.html
new file mode 100644
index 0000000..66af828
--- /dev/null
+++ b/tpl/json/settings.html
@@ -0,0 +1,63 @@
+{if condition="!$show_settings"}
+Edit homepage notice
+{if condition="$error"}{$error}
{/if}
+
+
+ Homepage notice :
+ {$notice}
+
+ Note : You can use HTML formatting in this form.
+
+
+
+
+
+
+{else}
+Change settings of your Bouffe@Ulm installation
+{if condition="$error"}{$error}
{/if}
+
+
+ Database
+ Note : Use these settings carefully. Your database won't be updated by the script as it was during install and you'll have to manually update it.
+ MySQL host :
+
+ MySQL login :
+
+ MySQL password :
+ Note : Leave the above field blank if you don't want to change your password.
+
+
+ Name of the MySQL database to use :
+ Note : You must create this database first.
+
+
+ Prefix for the created tables :
+ Note : Leave the field blank to not use any.
+
+
+ General options
+ Title to display in pages :
+
+ Base URL :
+ Note : This is the base URL from which you access this page. You must keep the trailing "/" in the above address.
+
+ Currency :
+
+ Timezone :
+ For example : Europe/Paris. See the doc for more info.
+
+
+ Template :
+
+ {loop="templates"}
+ {$value['option']}
+ {/loop}
+
+
Webmaster's email :
+
+
+
+
+{/if}