<?php
// vim: ts=2 sw=2
include_once "utils.php";
class DBConn {
protected $db = NULL;
protected $history_db = NULL;
protected $dbpath = NULL;
// using 'var' to define a property equals define the property using 'public'
var $history_dbname = 'easyio.db';
public static function instance() {
static $inst = NULL;
if ($inst === NULL) {
$inst = new DBConn();
}
return $inst;
}
private function __construct() {
$db_file_created = true;
try {
$dbname = 'cpt-web.db';
$this->dbpath = build_file_path(cptBaseDir(), 'app', $dbname);
if (!file_exists($this->dbpath))
$db_file_created = false;
$this->db = new PDO("sqlite:{$this->dbpath}");
} catch (PDOException $e) {
print "Error: " . $e->getMessage() . "<br/>";
die();
}
if (file_exists($this->dbpath) && !$db_file_created)
chmod($this->dbpath, 0666);
}
public function __destruct() {
$this->db = NULL;
$this->history_db = NULL;
}
public function db() {
return $this->db;
}
public function history_db() {
if (!isset($this->history_db)) {
try {
$history_dbpath = $_SERVER['DOCUMENT_ROOT'] . '/sdcard/' . $this->history_dbname;
$this->history_db = new PDO("sqlite:{$history_dbpath}");
} catch (PDOException $e) {
print "Error: " . $e->getMessage() . "<br/>";
die();
}
}
return $this->history_db;
}
public function getColumnNames($dbh, $table) {
$col_names = array() ;
$stmt = $dbh->prepare("SELECT sql FROM sqlite_master WHERE tbl_name = ':table'") ;
$stmt->bindValue(':table', $table);
$stmt->execute() ;
$row = $stmt->fetch() ;
$sql = $row[0] ;
$r = preg_match("/\(\s*(\S+)[^,)]*/", $sql, $m, PREG_OFFSET_CAPTURE) ;
while ($r) {
array_push( $col_names, $m[1][0] ) ;
$r = preg_match("/,\s*(\S+)[^,)]*/", $sql, $m, PREG_OFFSET_CAPTURE, $m[0][1] + strlen($m[0][0]) ) ;
}
return $col_names;
}
};
class BaseModel {
public function create($attrs) {
$tblName = $this->tableName();
if (is_null($tblName))
return NULL;
if (!isset($attrs))
return NULL;
$db = DBConn::instance()->db();
$cols = implode(',', array_keys($attrs));
$vals = array();
foreach(array_keys($attrs) as $k) {
$vals[] = ":$k";
}
$vals = implode(',', $vals);
$command = "INSERT INTO {$tblName} ($cols) VALUES ($vals);";
$stmt = $db->prepare($command);
foreach($attrs as $k=>$v) {
$stmt->bindValue(":$k", $v);
}
if ($stmt->execute())
return $db->lastInsertId();
else
return false;
}
public function update($attrs, $selectors) {
$tblName = $this->tableName();
if (is_null($tblName))
return NULL;
if (!isset($attrs) || !isset($selectors))
return NULL;
$db = DBConn::instance()->db();
$assignments = array();
foreach(array_keys($attrs) as $k) {
$assignments[] = "$k=?";
}
$assignment = implode(',', $assignments);
$conditions = array();
foreach(array_keys($selectors) as $k) {
$conditions[] = "$k=?";
}
$condition = implode(' AND ', $conditions);
$command = "UPDATE {$tblName} SET {$assignment} WHERE {$condition}";
$stmt = $db->prepare($command);
$index = 1;
foreach(array_keys($attrs) as $k) {
$stmt->bindValue($index, $attrs[$k]);
++$index;
}
foreach(array_keys($selectors) as $k) {
$stmt->bindValue($index, $selectors[$k]);
++$index;
}
$stmt->execute();
return true;
}
public function read() {
}
public function delete() {
}
protected function tableName() {
return NULL;
}
protected function find_by($colname, $value) {
$tblName = $this->tableName();
if (is_null($tblName))
return NULL;
$db = DBConn::instance()->db();
$query = "SELECT * FROM {$tblName} WHERE {$colname} = ?";
$stmt = $db->prepare($query);
$stmt->bindValue(1, $value);
$stmt->execute();
return $stmt->fetchAll();
}
protected function find_by2($attrs) {
$tblName = $this->tableName();
if (is_null($tblName))
return NULL;
$conditions = array();
foreach(array_keys($attrs) as $k) {
$conditions[] = "$k=:$k";
}
$condition = implode(' AND ', $conditions);
$db = DBConn::instance()->db();
$query = "SELECT * FROM {$tblName} WHERE {$condition}";
$stmt = $db->prepare($query);
foreach(array_keys($attrs) as $k) {
$stmt->bindValue(":$k", $attrs[$k]);
}
$stmt->execute();
return $stmt->fetchAll();
}
};
class Permission extends BaseModel {
protected function tableName() {
return 'permissions';
}
public function permissions($user_id=null) {
$db = DBConn::instance()->db();
$stmt = null;
if (is_null($user_id)) {
$query = <<<SQL
SELECT u.id as user_id, u.name as name, u.home_page as home_page, u.dev_readable as dev_readable, u.dev_writable as dev_writable, p.path, p.readable, p.writable
FROM users AS u LEFT OUTER JOIN permissions AS p ON u.id = p.user_id
ORDER BY user_id DESC;
SQL;
$stmt = $db->prepare($query);
} else {
$query = <<<SQL
SELECT u.id as user_id, u.name as name, u.home_page as home_page, u.dev_readable as dev_readable, u.dev_writable as dev_writable, p.path, p.readable, p.writable
FROM users AS u LEFT OUTER JOIN permissions AS p ON u.id = ? and u.id = p.user_id;
SQL;
$stmt = $db->prepare($query);
$stmt->bindValue(1, $user_id);
}
$stmt->execute();
return $stmt->fetchAll();
}
public function delPermissionsByUserId($user_id) {
$db = DBConn::instance()->db();
$command = "DELETE FROM permissions WHERE user_id = :user_id";
$stmt = $db->prepare($command);
$stmt->bindValue(':user_id', $user_id);
$stmt->execute();
}
public function findByUserAndPath($user_id, $path) {
$db = DBConn::instance()->db();
$query = "SELECT * FROM {$this->tableName()} WHERE user_id = :user_id AND path = :path;";
$stmt = $db->prepare($query);
$stmt->bindValue(':user_id', $user_id);
$stmt->bindValue(':path', $path);
$stmt->execute();
return $stmt->fetchAll();
}
};
class User extends BaseModel {
protected function tableName() {
return 'users';
}
public function findById($id) {
$rows = parent::find_by('id', $id);
if (sizeof($rows) == 0)
return false;
$this->attrs = $rows[0];
return true;
}
public function find($name) {
$rows = parent::find_by('name', $name);
if (sizeof($rows) == 0)
return false;
$this->attrs = $rows[0];
return true;
}
public function attr($name) {
return $this->attrs[$name];
}
public function authenticate($password) {
$checksum = sha1($password . $this->attr('salt'))
return $checksum == $this->attr('checksum');
}
public function authenticate2($authHash, $authRand) {
$checksum = sha1($this->attr('checksum') . $authRand)
return $checksum == $authHash;
}
public function changePassword($password) {
$checksum = sha1($password . $this->attr('salt'))
return $this->changePassword2($checksum);
}
public function changePassword2($checksum) {
$result = false;
$result = $this->update(array('checksum' => $checksum), array('id' => $this->attr('id')));
if ($result && $this->attr("name") == "admin")
updatePhpAdminAuth($this->attr('salt'), $checksum);
return $result;
}
public function changeHomePage($home_page) {
if (function_exists('filter_var'))
$home_page = filter_var($home_page, FILTER_SANITIZE_URL);
if ($home_page == $this->attr('home_page'))
return;
return $this->update(array('home_page' => $home_page), array('id' => $this->attr('id')));
}
public function createAccount($name, $password, $utility_enabled, $system_enabled, $account_management_enabled, $password_change_enabled, $dashboard_enabled, $dashboard_as_landing_page) {
if ($this->find($name))
return false;
$salt = randStr();
$checksum = sha1($password . $salt)
return $this->createAccount2($name, $checksum, $salt, $utility_enabled, $system_enabled, $account_management_enabled, $password_change_enabled, $dashboard_enabled, $dashboard_as_landing_page);
}
public function createAccount2($name, $checksum, $salt, $utility_enabled, $system_enabled, $account_management_enabled, $password_change_enabled, $dashboard_enabled, $dashboard_as_landing_page) {
if ($this->find($name))
return false;
$vals = array(
'name' => $name,
'salt' => $salt,
'checksum' => $checksum,
'utility_enabled' => $utility_enabled,
'system_enabled' => $system_enabled,
'account_management_enabled' => $account_management_enabled,
'password_change_enabled' => $password_change_enabled,
'dashboard_enabled' => $dashboard_enabled,
'dashboard_as_landing_page' => $dashboard_as_landing_page);
if ($dashboard_enabled == 't')
$vals['dev_readable'] = 't';
$this->create($vals);
return true;
}
private function hashPassword($password, $salt) {
return sha1($password . $salt)
}
public function isAdmin() {
return $this->attr('is_admin') == 't' ;
}
public function isUtilityEnabled() {
return $this->isAdmin() || $this->attr('utility_enabled') == 't';
}
public function isSystemEnabled() {
return $this->isAdmin() || $this->attr('system_enabled') == 't';
}
public function isAccountManagementEnabled() {
return $this->isAdmin() || $this->attr('account_management_enabled') == 't';
}
public function isPasswordChangeEnabled() {
return $this->isAdmin() || $this->attr('password_change_enabled') == 't';
}
public function isDashboardEnabled() {
return $this->attr('dashboard_enabled') == 't';
}
public function isDashboardLanding() {
return $this->attr('dashboard_as_landing_page') == 't';
}
public function can($action, $grPath=null) {
if ($this->isAdmin())
return true;
if (is_null($grPath))
{
if ($action == 'read')
return strcasecmp($this->attr('dev_readable'), 't') == 0;
else if ($action == 'write')
return strcasecmp($this->attr('dev_writable'), 't') == 0;
else
return false;
}
$perm = new Permission();
$perm_datas = $perm->findByUserAndPath($this->attr('id'), $grPath);
if (count($perm_datas) == 0)
return true;
foreach($perm_datas as $data) {
if (strcasecmp($data['readable'], 'f') == 0 || strcasecmp($data['readable'], 'false') == 0)
return false;
if ($action == 'write' && (strcasecmp($data['writable'], 'f') == 0 || strcasecmp($data['writable'], 'false') == 0))
return false;
}
return true;
}
public function canDashboard($action, $dashboardId) {
if ($this->isAdmin())
return true;
$perm_datas = DashboardPermission::findByUserAndDashboard($this->attr('id'), $dashboardId);
if (count($perm_datas) == 0)
return false;
foreach($perm_datas as $data) {
if (!isset($data[$action]))
continue;
return strcasecmp($data[$action], 't') == 0;
}
return true;
}
public function updatePermissions($perms, $dev_readable='f', $dev_writable='f') {
$user_id = $this->attr("id");
$new_datas = array();
if (isset($perms))
{
foreach($perms as $perm) {
$attrs = array();
$attrs['user_id'] = $user_id;
$attrs['path'] = $perm['path'];
if (!isset($attrs['path'])) {
return "invalid path";
}
$readable = (strcasecmp($perm['readable'], 'true') == 0) || (strcasecmp($perm['readable'], 't') == 0);
$attrs['readable'] = $readable ? 't' : 'f';
$writable = (strcasecmp($perm['writable'], 'true') == 0) || (strcasecmp($perm['writable'], 't') == 0);
$attrs['writable'] = $writable ? 't' : 'f';
$new_datas[] = $attrs;
}
}
$db = DBConn::instance()->db();
$db->beginTransaction();
// update dev perms
$dev_perm_data = array('dev_readable' => $dev_readable, 'dev_writable' => $dev_writable);
$result = $this->update($dev_perm_data, array('id' => $this->attr('id')));
if (!$result)
{
$db->rollBack();
return "update user's dev permission failed";
}
// update gr files permission
$model = new Permission();
$model->delPermissionsByUserId($user_id);
//TODO: optimize below loop to use query statement
foreach($new_datas as $attrs)
$model->create($attrs);
$db->commit();
return '';
}
public function updateDashboardPermissions($perms) {
$user_id = $this->attr("id");
$new_datas = array();
foreach($perms as $perm) {
$attrs = array();
$attrs['user_id'] = $user_id;
$attrs['dashboard_id'] = $perm['dashboardId'];
$attrs['canManageDataSource'] = $perm['canManageDataSource'];
$attrs['canManageWidget'] = $perm['canManageWidget'];
$attrs['canViewDashboard'] = $perm['canViewDashboard'];
$attrs['canWriteDataSource'] = $perm['canWriteDataSource'];
if (!isset($attrs['dashboard_id'])) {
return L("invalid dashboard_id");
}
$new_datas[] = $attrs;
}
$db = DBConn::instance()->db();
$db->beginTransaction();
$model = new DashboardPermission();
$model->delPermissionsByUserId($user_id);
//TODO: optimize below loop to use query statement
foreach($new_datas as $attrs)
$model->create($attrs);
$db->commit();
return '';
}
public function grBlackList() {
$user_id = $this->attr("id");
$db = DBConn::instance()->db();
$query = <<<SQL
SELECT p.path as path
FROM users AS u JOIN permissions AS p ON u.id = ? and u.id = p.user_id and p.readable = 'f' and p.writable = 'f';
SQL;
$stmt = $db->prepare($query);
$stmt->bindValue(1, $user_id);
$stmt->execute();
return $stmt->fetchAll(PDO::FETCH_COLUMN, 0);
}
public function updateAccount($values) {
$user_id = $this->attr("id");
$db = DBConn::instance()->db();
$db->beginTransaction();
if (array_key_exists('password', $values)) {
$this->changePassword($values['password']);
unset($values['password']);
}
if (array_key_exists('authHash', $values)) {
$this->changePassword2($values['authHash']);
unset($values['authHash']);
}
//when user is dashboard enabled, then it should also have 'dev_readable'
//perm, otherwise data polling will not work in dashboard
if (array_key_exists('dashboard_enabled', $values)) {
if ($values['dashboard_enabled'] == 't')
$values['dev_readable'] = 't';
}
unset($values['id']);
//FIXME: this may cause SQL injection issue, since the keys in $values can
//possibly provided by user
if (!empty($values))
$this->update($values, array('id' => $user_id));
$db->commit();
}
public function deleteAccount() {
$user_id = $this->attr("id");
$db = DBConn::instance()->db();
$db->beginTransaction();
$tblName = $this->tableName();
$command = "DELETE FROM {$tblName} WHERE id = :id ;";
$stmt = $db->prepare($command);
$stmt->bindValue(':id', $user_id);
$stmt->execute();
$perm = new Permission();
$perm->delPermissionsByUserId($user_id);
$dperm = new DashboardPermission();
$dperm->delPermissionsByUserId($user_id);
$db->commit();
}
public function accounts($user_id=null) {
$db = DBConn::instance()->db();
$stmt = null;
if (is_null($user_id)) {
$query = <<<SQL
SELECT id as user_id, name, utility_enabled, system_enabled, account_management_enabled, password_change_enabled, dashboard_enabled, dashboard_as_landing_page
FROM users ORDER BY user_id DESC;
SQL;
$stmt = $db->prepare($query);
} else {
$query = <<<SQL
SELECT id as user_id, name, utility_enabled, system_enabled, account_management_enabled, password_change_enabled, dashboard_enabled, dashboard_as_landing_page
FROM users WHERE id = ? ORDER BY user_id DESC;
SQL;
$stmt = $db->prepare($query);
$stmt->bindValue(1, $user_id);
}
$stmt->execute();
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
protected $attrs = NULL;
};
function output_history_data($stmt, &$formatter, $download_file_name, $orig_columns=null, $bool_text_mappings=null, $dbh=null, $table=null, $dt_tz=null) {
$first = true;
$utc_tz = new DateTimeZone('UTC');
$formatter->writeHeader($download_file_name);
$dt_format = 'Y-m-d H:i:s';
$stmt->setFetchMode(PDO::FETCH_ASSOC);
$bool_col_indexes = array();
while($row = $stmt->fetch()) {
//use '_dt' to overwrite 'dt' column
if (array_key_exists('dt', $row) && array_key_exists('_dt', $row))
{
$row['dt'] = $row['_dt'];
unset($row['_dt']);
}
//get headers row
if ($first) {
$first = false;
$formatter->writeRow(array_keys($row));
if (!is_null($bool_text_mappings)) {
$col_count = count(array_keys($row));
for($i=0; $i< $col_count; ++$i) {
$meta = $stmt->getColumnMeta($i);
if (!is_null($meta) && array_key_exists('sqlite:decl_type', $meta) && $meta['sqlite:decl_type'] == 'BOOLEAN') {
$bool_col_indexes[] = $i;
}
}
}
}
//convert dt to given timezone
if (isset($dt_tz) && $dt_tz->getName() != 'UTC' && array_key_exists('dt', $row)) {
$dt_in_utc = DateTime::createFromFormat($dt_format, $row['dt'], $utc_tz);
$row['dt'] = $dt_in_utc->setTimeZone($dt_tz)->format($dt_format);
}
$col_values = array_values($row);
if (!is_null($bool_text_mappings)) {
// convert bool to user given boolean text if there is any
for($i=0; $i<count($bool_col_indexes); ++$i) {
$bool_index = $bool_col_indexes[$i];
$bool_val = $col_values[$bool_index];
if (!array_key_exists($bool_val, $bool_text_mappings))
continue;
$bool_text = $bool_text_mappings[$bool_val];
if (!is_null($bool_text))
$col_values[$bool_index] = $bool_text;
}
}
$formatter->writeRow($col_values);
}
// error_log("### elapsed after fetch: " . $etime->elapsed());
//when there is no data, try to return row of columns
if ($formatter->isEmpty() && (!is_null($orig_columns))) {
if ($orig_columns != '*') {
$formatter->writeRow(explode(',', $orig_columns));
} else {
if (!is_null($dbh) && !is_null($table)) {
$col_names = DBConn::instance()->getColumnNames($dbh, $table);
$formatter->writeRow($col_names);
}
}
}
$formatter->writeFooter();
$formatter->done();
};
class Dashboard extends BaseModel {
protected $attrs = array();
protected function tableName() {
return 'dashboards';
}
public function findById($id) {
$rows = parent::find_by('id', $id);
if (sizeof($rows) == 0)
return false;
$this->attrs = $rows[0];
return true;
}
public function isNull() {
return !isset($this->attrs) || empty($this->attrs);
}
public function attr($name) {
if (isset($this->attrs[$name]))
return $this->attrs[$name];
else
return null;
}
public function toJson() {
return map2json($this->attrs);
}
public function createDashboard($name, $content) {
$vals = array(
'name' => $name,
'content' => $content,
'parent_id' => 1
);
return $this->create($vals);
}
public function saveDashboard($name=NULL, $content=NULL) {
$vals = array();
if ($name)
$vals['name'] = $name;
if ($content)
$vals['content'] = $content;
return $this->update($vals, array('id' => $this->attr('id')));
}
public function renameDashboard($id, $new_name) {
if (!$this->findById($id))
return false;
return $this->saveDashboard($new_name);
}
public static function updateLayout($id, $parent_id, $sibling_ids) {
$stmt = null;
$db = DBConn::instance()->db();
$db->beginTransaction();
$query = 'UPDATE dashboards SET parent_id=? WHERE id=?;';
$stmt = $db->prepare($query);
$stmt->bindValue(1, $parent_id);
$stmt->bindValue(2, $id);
$stmt->execute();
$query = 'UPDATE dashboards SET parent_id=?, order_val=? WHERE id=?;';
$stmt = $db->prepare($query);
foreach($sibling_ids as $index=>$sid) {
$stmt->bindValue(1, $parent_id);
$stmt->bindValue(2, $index+1);
$stmt->bindValue(3, $sid);
$stmt->execute();
}
return $db->commit();
}
public static function deleteDashboard($id_list) {
$db = DBConn::instance()->db();
$db->beginTransaction();
$command = "DELETE FROM dashboards WHERE id IN ( :ids ) ;";
$stmt = $db->prepare($command);
$stmt->bindValue(':ids', implode(",", $id_list));
if (!$stmt->execute())
{
$db->rollBack();
return false;
}
foreach($id_list as $dashboardId)
DashboardPermission::delPermissionsByDashboardId($dashboardId);
$db->commit();
return true;
}
public static function dashboardList() {
$db = DBConn::instance()->db();
$stmt = null;
$query = <<<SQL
SELECT id, name, parent_id FROM dashboards ORDER BY parent_id, order_val ASC;
SQL;
$stmt = $db->prepare($query);
$stmt->execute();
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
public static function indexDashboardByUser($user_id) {
$db = DBConn::instance()->db();
$query = <<<SQL
SELECT id FROM dashboards WHERE parent_id = 1
AND id NOT IN (SELECT dashboard_id FROM dashboard_permissions WHERE user_id = :user_id AND canViewDashboard = 'f') ORDER BY order_val, id ASC LIMIT 1;
SQL;
$stmt = $db->prepare($query);
$stmt->bindValue(':user_id', $user_id);
$stmt->execute();
$dashboardId = $stmt->fetchColumn();
$stmt->closeCursor();
$dashboard = new Dashboard();
if (isset($dashboardId))
$dashboard->findById($dashboardId);
return $dashboard;
}
};
class DashboardPermission extends BaseModel {
protected $attrs = array();
protected function tableName() {
return 'dashboard_permissions';
}
public function attr($name) {
return $this->attrs[$name];
}
public function permissions($user_id=null, $dashboard_id=null) {
$db = DBConn::instance()->db();
$stmt = null;
$query = <<<SQL
SELECT u.id as userId, u.name as userName, d.id as dashboardId, d.name as pageName, p.canManageDataSource, p.canManageWidget, p.canViewDashboard, p.canWriteDataSource
FROM users AS u JOIN dashboard_permissions AS p ON u.id = p.user_id JOIN dashboards as d ON d.id = p.dashboard_id
SQL;
$where_conditions = array();
if (!is_null($user_id))
$where_conditions[] = ' u.id = :user_id ';
if (!is_null($dashboard_id))
$where_conditions[] = ' d.id = :dashboard_id ';
if (!empty($where_conditions))
$query = $query . ' WHERE ' . implode(' AND ', $where_conditions);
$query = $query . ' ORDER BY userId DESC;';
$stmt = $db->prepare($query);
if (!is_null($user_id))
$stmt->bindValue(':user_id', $user_id);
if (!is_null($dashboard_id))
$stmt->bindValue(':dashboard_id', $dashboard_id);
$stmt->execute();
$perms = $stmt->fetchAll(PDO::FETCH_ASSOC);
$users = array();
$dashboards = array();
if (is_null($user_id))
$users = $db->query('SELECT id AS userId, name AS userName, role_id FROM users')->fetchAll();
else {
$user_stmt = $db->prepare("SELECT id AS userId, name AS userName, role_id FROM users WHERE id = ?");
$user_stmt->bindValue(1, $user_id);
$user_stmt->execute();
$users = $user_stmt->fetchAll();
}
if (is_null($dashboard_id))
$dashboards = $db->query('SELECT id AS dashboardId, name AS pageName FROM dashboards WHERE id != 1 ')->fetchAll();
else {
$dashboards_stmt = $db->prepare('SELECT id AS dashboardId, name AS pageName FROM dashboards WHERE id = ? ');
$dashboards_stmt->bindValue(1, $dashboard_id);
$dashboards_stmt->execute();
$dashboards = $dashboards_stmt->fetchAll();
}
$result = array();
foreach($users as $user) {
$userId = $user['userId'];
$userName = $user['userName'];
$roleId = intval($user['role_id']);
foreach($dashboards as $dashboard) {
$dashboardId = $dashboard['dashboardId'];
$pageName = $dashboard['pageName'];
$permExisted = false;
foreach($perms as $perm) {
if ($perm['userId'] == $userId && $perm['userName'] == $userName && $perm['pageName'] == $pageName)
{
$permExisted = true;
$row = array();
foreach($perm as $key => $val)
$row[$key] = $val;
$result[] = $row;
break;
}
}
if (!$permExisted) {
$canManageDataSource = $roleId == 1;
$canManageWidget = $roleId == 1 || $roleId == 2;
$canWriteDataSource = $roleId == 1 || $roleId == 2 || $roleId == 3;
$canViewDashboard = true;
$result[] = array(
'userId' => $userId,
'userName' => $userName,
'dashboardId' => $dashboardId,
'pageName' => $pageName,
'canManageDataSource' => ($canManageDataSource ? 't' : 'f'),
'canManageWidget' => ($canManageWidget ? 't' : 'f'),
'canWriteDataSource' => ($canWriteDataSource ? 't' : 'f'),
'canViewDashboard' => ($canViewDashboard ? 't' : 'f')
);
}
}
}
return $result;
}
public function delPermissionsByUserId($user_id) {
$db = DBConn::instance()->db();
$command = "DELETE FROM dashboard_permissions WHERE user_id = :user_id";
$stmt = $db->prepare($command);
$stmt->bindValue(':user_id', $user_id);
$stmt->execute();
}
public static function delPermissionsByDashboardId($dashboard_id) {
$db = DBConn::instance()->db();
$command = "DELETE FROM dashboard_permissions WHERE dashboard_id = :dashboard_id";
$stmt = $db->prepare($command);
$stmt->bindValue(':dashboard_id', $dashboard_id);
$stmt->execute();
}
public static function findByUserAndDashboard($user_id, $dashboard_id) {
$db = DBConn::instance()->db();
$query = "SELECT * FROM dashboard_permissions WHERE user_id = :user_id AND dashboard_id = :dashboard_id;";
$stmt = $db->prepare($query);
$stmt->bindValue(':user_id', $user_id);
$stmt->bindValue(':dashboard_id', $dashboard_id);
$stmt->execute();
return $stmt->fetchAll();
}
};
class AuthKeys extends BaseModel {
protected $attrs = array();
protected function tableName() {
return 'auth_keys';
}
public function attr($name) {
return $this->attrs[$name];
}
public function find($key) {
$rows = parent::find_by('key', $key);
if (sizeof($rows) == 0)
return false;
$this->attrs = $rows[0];
return true;
}
public function createKey($note, $expired_at) {
$key = randStr(16);
$vals = array(
'key' => $key,
'note' => $note,
'expired_at' => $expired_at);
$this->create($vals);
return $key;
}
public function updateKey($key, $note, $expired_at) {
return $this->update(array('note' => $note, 'expired_at' => $expired_at),
array('key' => $key));
}
public function deleteKey($key) {
$db = DBConn::instance()->db();
$command = "DELETE FROM auth_keys WHERE key = :key";
$stmt = $db->prepare($command);
$stmt->bindValue(':key', $key);
$stmt->execute();
}
public function keys() {
$db = DBConn::instance()->db();
$query = "SELECT id, key, note, expired_at FROM auth_keys ORDER BY created_at DESC;";
$stmt = $db->prepare($query);
$stmt->execute();
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
public function isExpired() {
$tz = new DateTimeZone('UTC');
$now = new DateTime('NOW', $tz);
$expired_at = DateTime::createFromFormat('Y-m-d H:i:s', $this->attr('expired_at'), $tz);
return $now >= $expired_at;
}
public static function isValid($key) {
$instance = new AuthKeys();
if (!$instance->find($key))
return false;
return $instance->isExpired();
}
};
class FailedAuthCounter extends BaseModel {
protected $attrs = array();
protected function tableName() {
return 'failed_auth_counter';
}
public function attr($name) {
return $this->attrs[$name];
}
public function getCounter($name, $clientIP) {
$rows = parent::find_by2(array('name'=> $name, 'client_ip' => $clientIP));
if (sizeof($rows) == 0)
return 0;
$this->attrs = $rows[0];
return intval($this->attrs['counter']);
}
public function incrCounter($name, $clientIP) {
if (is_null($name))
return false;
$tblName = $this->tableName();
$rows = parent::find_by2(array('name' => $name, 'client_ip' => $clientIP));
if (sizeof($rows) == 0) {
$this->create(array('name' => $name, 'client_ip' => $clientIP, 'counter' => 1, 'lockout_time' => 0));
} else {
$this->attrs = $rows[0];
$counter = intval($this->attrs['counter']);
$this->update(array('counter' => $counter+1),
array('name' => $name, 'client_ip' => $clientIP));
}
return true;
}
public function delRecord($name, $clientIP) {
$db = DBConn::instance()->db();
$tblName = $this->tableName();
$command = "DELETE FROM {$tblName} WHERE name= :name and client_ip= :client_ip";
$stmt = $db->prepare($command);
$stmt->bindValue(':name', $name);
$stmt->bindValue(':client_ip', $clientIP);
$stmt->execute();
}
public function getLockoutTime($name, $clientIP) {
$rows = parent::find_by2(array('name' => $name,
'client_ip' => $clientIP));
if (sizeof($rows) == 0)
return 0;
$this->attrs = $rows[0];
return intval($this->attrs['lockout_time']);
}
public function updateLockoutTime($name, $clientIP, $now) {
return $this->update(array('lockout_time' => $now),
array('name' => $name, 'client_ip' => $clientIP));
}
};
?>