Continued work on new permissions system, Removed unused functions from common, Added initial version specific update function,

This commit is contained in:
xevidos 2019-07-04 01:50:29 -04:00
parent 492e372c5d
commit 3d5df9aaff
9 changed files with 280 additions and 183 deletions

View File

@ -107,56 +107,6 @@ class Common {
// New Methods
//////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////
// Check access to application
//////////////////////////////////////////////////////////////////
public static function check_access( $action = "return" ) {
/*if( ! self::check_session() ) {
session_destroy();
self::return( formatJSEND( "error", "Error fetching project information." ), "exit" );
}*/
}
//////////////////////////////////////////////////////////////////
// Check access to a project
//////////////////////////////////////////////////////////////////
public static function check_project_access( $project_path, $action ) {
global $sql;
$query = "SELECT * FROM projects WHERE name=? AND path=? AND ( owner=? OR owner='nobody' );";
$bind_variables = array( $project_name, $project_path, $_SESSION["user"] );
$return = $sql->query( $query, $bind_variables, formatJSEND( "error", "Error checking project access." ) );
if( ! empty( $return ) ) {
try {
$users = json_decode( $return["access"] );
} catch( exception $e ) {
$users = array();
}
if( $return["owner"] == 'nobody' || $return["owner"] == $_SESSION["user"] || ( in_array( $_SESSION["user"], $users ) && ! empty( $users ) ) ) {
$return = true;
} else {
$return = false;
}
} else {
$return = false;
}
self::return( $return, $action );
}
public static function get_user_id( $username ) {
global $sql;

View File

@ -350,6 +350,8 @@ class Filemanager extends Common {
public function open() {
$response = array();
if ( is_file( $this->path ) ) {
$output = file_get_contents( $this->path );
@ -368,19 +370,22 @@ class Filemanager extends Common {
}
}
$this->status = "success";
$this->data = '"content":' . json_encode( $output );
$mtime = filemtime( $this->path );
$this->data .= ', "mtime":'.$mtime;
$this->data .= ', "access":'. $this->access;
$this->data .= ', "read_only":'. ( Permissions::check_access( "read", $this->access ) && ! Permissions::check_access( "write", $this->access ) );
$response["status"] = "success";
$response["data"] = array(
"content" => $output,
"mtime" => $mtime,
"access" => $this->access,
"read_only" => ( Permissions::check_access( "read", $this->access ) && ! Permissions::check_access( "write", $this->access ) ),
);
} else {
$this->status = "error";
$this->message = "Not A File :" . $this->path;
$response = array(
"status" => "error",
"message" => "Not A File :" . $this->path,
);
}
$this->respond();
exit( json_encode( $response ) );
}
//////////////////////////////////////////////////////////////////
@ -388,7 +393,7 @@ class Filemanager extends Common {
//////////////////////////////////////////////////////////////////
public function openinbrowser() {
$protocol = ( ( ! empty( $_SERVER['HTTPS'] ) && $_SERVER['HTTPS'] != 'off' ) || $_SERVER['SERVER_PORT'] == 443 ) ? "https://" : "http://";
$domainName = $_SERVER['HTTP_HOST'];
$url = $protocol . WSURL . '/' . $this->rel_path;
@ -402,49 +407,64 @@ class Filemanager extends Common {
//////////////////////////////////////////////////////////////////
public function create() {
// Create file
if ( $this->type == "file" ) {
$response = array();
if( Permissions::has_create( $this->path ) ) {
if ( ! file_exists( $this->path ) ) {
// Create file
if ( $this->type == "file" ) {
if ( $file = fopen( $this->path, 'w' ) ) {
if ( ! file_exists( $this->path ) ) {
// Write content
if ( $this->content ) {
if ( $file = fopen( $this->path, 'w' ) ) {
fwrite( $file, $this->content );
// Write content
if ( $this->content ) {
fwrite( $file, $this->content );
}
fclose( $file );
$response["data"] = array(
"content" => $this->content,
"mtime" => filemtime( $this->path ),
"access" => $this->access,
"read_only" => ( Permissions::check_access( "read", $this->access ) && ! Permissions::check_access( "write", $this->access ) ),
);
$this->status = "success";
} else {
$this->status = "error";
$this->message = "Cannot Create File";
}
$this->data = '"mtime":' . filemtime( $this->path );
fclose( $file );
} else {
$this->status = "error";
$this->message = "File Already Exists";
}
}
// Create directory
if ( $this->type == "directory" ) {
if ( ! is_dir( $this->path ) ) {
mkdir( $this->path );
$this->status = "success";
} else {
$this->status = "error";
$this->message = "Cannot Create File";
$this->message = "Directory Already Exists";
}
} else {
$this->status = "error";
$this->message = "File Already Exists";
}
}
// Create directory
if ( $this->type == "directory" ) {
} else {
if ( ! is_dir( $this->path ) ) {
mkdir( $this->path );
$this->status = "success";
} else {
$this->status = "error";
$this->message = "Directory Already Exists";
}
$this->status = "error";
$this->message = "No create access.";
}
$this->respond();
$response["status"] = $this->status;
$response["message"] = $this->message;
exit( json_encode( $response ) );
}
//////////////////////////////////////////////////////////////////
@ -453,67 +473,70 @@ class Filemanager extends Common {
public function delete( $keep_parent = false ) {
if( ! Permissions::has_delete( $this->path ) ) {
$this->status = "error";
$this->message = "No access.";
$this->respond();
return;
}
$response = array();
function rrmdir( $path, $follow, $keep_parent = false ) {
if( Permissions::has_delete( $this->path ) ) {
if ( is_file( $path ) ) {
unlink( $path );
} else {
$files = array_diff( scandir( $path ), array( '.', '..' ) );
foreach ( $files as $file ) {
if ( is_link( $path . "/" . $file ) ) {
if ( $follow ) {
rrmdir( $path . "/" . $file, $follow, false);
}
unlink( $path . "/" . $file );
} elseif ( is_dir( $path . "/" . $file ) ) {
rrmdir( $path . "/" . $file, $follow, false );
} else {
unlink( $path . "/" . $file );
}
}
if( $keep_parent === false ) {
rmdir( $path );
return;
function rrmdir( $path, $follow, $keep_parent = false ) {
if ( is_file( $path ) ) {
unlink( $path );
} else {
return;
$files = array_diff( scandir( $path ), array( '.', '..' ) );
foreach ( $files as $file ) {
if ( is_link( $path . "/" . $file ) ) {
if ( $follow ) {
rrmdir( $path . "/" . $file, $follow, false);
}
unlink( $path . "/" . $file );
} elseif ( is_dir( $path . "/" . $file ) ) {
rrmdir( $path . "/" . $file, $follow, false );
} else {
unlink( $path . "/" . $file );
}
}
if( $keep_parent === false ) {
rmdir( $path );
return;
} else {
return;
}
}
}
}
if ( file_exists( $this->path ) ) {
if ( isset( $_GET['follow'] ) ) {
rrmdir( $this->path, true, $keep_parent );
if ( file_exists( $this->path ) ) {
if ( isset( $_GET['follow'] ) ) {
rrmdir( $this->path, true, $keep_parent );
} else {
rrmdir( $this->path, false, $keep_parent );
}
$this->status = "success";
} else {
rrmdir( $this->path, false, $keep_parent );
$this->status = "error";
$this->message = "Path Does Not Exist ";
}
$this->status = "success";
} else {
$this->status = "error";
$this->message = "Path Does Not Exist ";
$this->message = "No delete access.";
}
$this->respond();
$response["status"] = $this->status;
$response["message"] = $this->message;
exit( json_encode( $response ) );
}

View File

@ -884,6 +884,9 @@
.live( 'submit', function( e ) {
e.preventDefault();
$.get( _this.controller + '?action=delete&path=' + encodeURIComponent( path ), function( data ) {
console.log( data );
var deleteResponse = codiad.jsend.parse( data );
if( deleteResponse != 'error' ) {
var node = $( '#file-manager a[data-path="' + path + '"]' );

View File

@ -115,6 +115,28 @@ class Project extends Common {
}
}
public function check_duplicate( $full_path ) {
$pass = true;
$query = "SELECT id, path, owner FROM projects;";
$result = $sql->query( $query, array(), array(), "fetchAll" );
if( ! empty( $result ) ) {
foreach( $result as $row => $project ) {
$full_project_path = Common::isAbsPath( $project["path"] ) ? $project["path"] : WORKSPACE . "/{$project["path"]}";
if( ! ( strpos( $full_path, $full_project_path ) === FALSE ) ) {
$pass = false;
break;
}
}
}
return $pass;
}
public function check_owner( $path = null, $exclude_public = false ) {
if( $path === null ) {
@ -336,9 +358,9 @@ class Project extends Common {
owner=?
OR owner='nobody'
OR id IN ( SELECT project FROM access WHERE user = ? )
) ORDER BY name;";
) ORDER BY name LIMIT 1;";
$bind_variables = array( $this->path, $_SESSION["user"], $_SESSION["user_id"] );
$return = $sql->query( $query, $bind_variables, array() )[0];
$return = $sql->query( $query, $bind_variables, array(), "fetch" );
if( ! empty( $return ) ) {
@ -375,18 +397,17 @@ class Project extends Common {
if( ! $this->public_project && ! $this->isAbsPath( $this->path ) ) {
$user_path = WORKSPACE . '/' . preg_replace( '/[^\w-]/', '', strtolower( $_SESSION["user"] ) );
$this->path = $_SESSION["user"] . '/' . $this->path;
}
$pass = $this->check_duplicate();
if ( $pass ) {
if( ! is_dir( $user_path ) ) {
mkdir( $user_path, 0755, true );
}
$this->path = $_SESSION["user"] . '/' . $this->path;
}
$pass = $this->checkDuplicate();
if ( $pass ) {
if ( ! $this->isAbsPath( $this->path ) ) {
mkdir( WORKSPACE . '/' . $this->path );
@ -407,7 +428,7 @@ class Project extends Common {
$allowed = true;
}
}
if ( ! $allowed) {
if ( ! $allowed ) {
die( formatJSEND( "error", "Absolute Path Only Allowed for " . WHITEPATHS ) );
}
@ -443,18 +464,18 @@ class Project extends Common {
$this->ExecuteCMD();
}
echo formatJSEND( "success", array( "name" => $this->name, "path" => $this->path ) );
exit( formatJSEND( "success", array( "name" => $this->name, "path" => $this->path ) ) );
} else {
echo formatJSEND( "error", "A Project With the Same Name or Path Exists" );
exit( formatJSEND( "error", "A Project With the Same Name or Path Exists" ) );
}
} else {
echo formatJSEND( "error", "Project Name/Folder not allowed" );
exit( formatJSEND( "error", "Project Name/Folder not allowed" ) );
}
} else {
echo formatJSEND( "error", "Project Name/Folder is empty" );
exit( formatJSEND( "error", "Project Name/Folder is empty" ) );
}
}
@ -495,37 +516,26 @@ class Project extends Common {
public function Delete() {
global $sql;
$query = "DELETE FROM projects WHERE path=? AND ( owner=? OR owner='nobody' );";
$bind_variables = array( $this->path, $_SESSION["user"] );
$return = $sql->query( $query, $bind_variables, 0, "rowCount" );
if( $return > 0 ) {
if( Permissions::has_owner( $this->path ) ) {
echo( formatJSEND( "success", "Successfully deleted $project_name" ) );
global $sql;
$query = "DELETE FROM projects WHERE path=?";
$bind_variables = array( $this->path, $_SESSION["user"] );
$return = $sql->query( $query, $bind_variables, 0, "rowCount" );
if( $return > 0 ) {
exit( formatJSEND( "success", "Successfully deleted project." ) );
} else {
exit( formatJSEND( "error", "Error deleting project" ) );
}
} else {
echo formatJSEND( "error", "Error deleting project $project_name" );
exit( formatJSEND( "error", "You do not have permission to delete this project" ) );
}
}
//////////////////////////////////////////////////////////////////
// Check Duplicate
//////////////////////////////////////////////////////////////////
public function CheckDuplicate() {
$pass = true;
foreach ( $this->projects as $project => $data ) {
if ( $data['name'] == $this->name || $data['path'] == $this->path ) {
$pass = false;
}
}
return $pass;
}
//////////////////////////////////////////////////////////////////
// Sanitize Path
//////////////////////////////////////////////////////////////////

View File

@ -191,7 +191,7 @@ if( $_GET['action'] == 'get_owner' ) {
if( $_GET['action'] == 'open' ) {
if( isset( $_GET['path'] ) && Permissions::has_read( $_GET['path'] ) ) {
if( ! isset( $_GET['path'] ) || ! Permissions::has_read( $_GET['path'] ) ) {
die( formatJSEND( "error", "No Access to path " . $_GET['path'] ) );
}

View File

@ -79,7 +79,7 @@
console.log( access, username, project_path, project_id );
$.get( _this.controller + '?action=add_user&project_path=' + encodeURIComponent( project_path ) + '&project_id=' + encodeURIComponent( project_id ) + '&username=' + encodeURIComponent( username ) + '&access=' + encodeURIComponent( access ), function( data ) {
$.get( _this.controller + '?action=add_user&path=' + encodeURIComponent( project_path ) + '&id=' + encodeURIComponent( project_id ) + '&username=' + encodeURIComponent( username ) + '&access=' + encodeURIComponent( access ), function( data ) {
let response = codiad.jsend.parse( data );
console.log( response );

View File

@ -222,6 +222,25 @@ class sql {
//echo var_dump( $error->getMessage() );
}
if( DBTYPE === "mysql" || DBTYPE === "pgsql" ) {
try {
$projects = $this->query( "ALTER TABLE projects DROP CONSTRAINT path1500owner255;", array(), 0, "rowCount", "exception" );
} catch( Exception $error ) {
//echo var_dump( $error->getMessage() );
}
try {
$projects = $this->query( "ALTER TABLE active DROP CONSTRAINT username255path1500;", array(), 0, "rowCount", "exception" );
} catch( Exception $error ) {
//echo var_dump( $error->getMessage() );
}
}
}
return $result;

View File

@ -178,6 +178,12 @@ class updater {
$sql = new sql();
$connection = $sql->connect();
$result = $sql->create_default_tables();
$upgrade_function = str_replace( ".", "_", $this->update::VERSION );
if( is_callable( array( $this, $upgrade_function ) ) ) {
$this->$upgrade_function();
}
}
function check_update() {
@ -454,7 +460,6 @@ class updater {
$this->backup();
try {
$sessions = "../../data/sessions";
@ -592,6 +597,96 @@ class updater {
$return = "true";
}
}
function v_2_9_6() {
//This function should run to upgrade our database version from less than 2.9.6
$sql_conversions = new sql_conversions();
try {
$access_query = "INSERT INTO access( project, user, level ) VALUES ";
$projects = $this->query( "SELECT id, access FROM projects", array(), array(), "fetchAll", "exception" );
$users = $this->query( "SELECT id, username FROM users", array(), array(), "fetchAll", "exception" );
$delete = Permissions::LEVELS["delete"];
foreach( $users as $row => $user ) {
foreach( $projects as $row => $project ) {
$access = json_decode( $project["access"], true );
if( ! is_array( $access ) || empty( $access ) ) {
continue;
}
foreach( $access as $granted_user ) {
if( $granted_user == $user["username"] ) {
$access_query .= "( {$project["id"]}, {$user["id"]}, $delete ),";
}
}
}
}
if( $access_query !== "INSERT INTO access( project, user, level ) " ) {
$result = $this->query( substr( $access_query, 0, -1 ), array(), 0, "rowCount", "exception" );
}
$result = $this->query( "ALTER TABLE projects DROP COLUMN access", array(), 0, "rowCount" );
} catch( Exception $error ) {
//The access field is not there.
//echo var_export( $error->getMessage(), $access_query );
}
try {
$update_query = "";
$projects = $this->query( "SELECT id, path FROM projects", array(), array(), "fetchAll", "exception" );
$result = $this->query( "SELECT project FROM users", array(), array(), "fetchAll", "exception" );
$convert = false;
$delete = Permissions::LEVELS["delete"];
foreach( $projects as $row => $project ) {
if( $project["path"] == $user["project"] ) {
$update_query .= "UPDATE users SET project={$project["id"]};";
}
}
if( $convert ) {
//change project to users table
$result = $this->query( "ALTER TABLE users DROP COLUMN project", array(), array(), "rowCount", "exception" );
$result = $this->query( "ALTER TABLE users ADD COLUMN project " . $sql_conversions->data_types["int"][DBTYPE], array(), array(), "rowCount", "exception" );
$result = $this->query( $update_query, array(), array(), "rowCount", "exception" );
}
} catch( Exception $error ) {
//echo var_dump( $error->getMessage() );
}
$constraint = ( DBTYPE == "mysql" ) ? "INDEX" : "CONSTRAINT";
try {
$projects = $this->query( "ALTER TABLE projects DROP $constraint path1500owner255;", array(), 0, "rowCount", "exception" );
} catch( Exception $error ) {
//echo var_dump( $error->getMessage() );
}
try {
$projects = $this->query( "ALTER TABLE active DROP $constraint username255path1500;", array(), 0, "rowCount", "exception" );
} catch( Exception $error ) {
//echo var_dump( $error->getMessage() );
}
}
}
if( isset( $_GET["action"] ) && $_GET["action"] !== '' ) {

View File

@ -126,7 +126,7 @@
create_default_tables: function() {
jQuery.ajax({
url: this.controller,
type: "POST",
dataType: 'html',
@ -137,12 +137,9 @@
let response = codiad.jsend.parse( data );
if( response.status != 'error' ) {
if( response != 'error' ) {
codiad.message.success( i18n( 'Created Default Tables' ) );
} else {
codiad.message.error( i18n( 'Error Creating Default Tables' ) );
}
console.log( data );
},