diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0270670 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.scannerwork \ No newline at end of file diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100755 index 0000000..d6a386c --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,24 @@ +stages: + - build + - test + - deploy + +build: + stage: build + script: + - echo "Building the app this does nothing." + +test: + stage: test + script: + - echo "Testing the app." + - /home/xevidos/scripts/sonar-codiad.sh + only: + - development + +deploy_staging: + stage: deploy + script: + - echo "Deploy to staging server this does nothing." + only: + - master diff --git a/common.php b/common.php index f148ef4..4205de7 100755 --- a/common.php +++ b/common.php @@ -99,21 +99,7 @@ class Common { // New Methods ////////////////////////////////////////////////////////////////// - public static function return( $output, $action = "return" ) { - - switch( $action ) { - - case( "exit" ): - - exit( $output ); - break; - - case( "return" ): - - return( $output ); - break; - } - } + ////////////////////////////////////////////////////////////////// // Check access to application @@ -121,11 +107,11 @@ class Common { public static function check_access( $action = "return" ) { - if( ! self::check_session() ) { + /*if( ! self::check_session() ) { session_destroy(); self::return( formatJSEND( "error", "Error fetching project information." ), "exit" ); - } + }*/ } ////////////////////////////////////////////////////////////////// @@ -165,19 +151,73 @@ class Common { self::return( $return, $action ); } - ////////////////////////////////////////////////////////////////// - // Check Session / Key - ////////////////////////////////////////////////////////////////// - - public static function check_session( $action = "return" ) { + public static function get_users( $return = "return" ) { + $sql = "SELECT `username` FROM `users`;"; + $bind = ""; + $bind_variables = array(); + $result = sql::sql( $sql, $bind, $bind_variables, formatJSEND( "error", "Error checking users." ) ); + $user_list = array(); - if( ! isset( $_SESSION['user'] ) && ! in_array( $key, $api_keys ) ) { + foreach( $result as $row ) { - //exit('{"status":"error","message":"Authentication Error"}'); - exit( '{"status":"error","message":"Authentication Error"}' ); + array_push( $user_list, $row["username"] ); } + + if( mysqli_num_rows( $result ) > 0 ) { + + switch( $return ) { + + case( "json" ): + + $return = json_encode( $user_list ); + break; + + case( "return" ): + + $return = $user_list; + break; + } + } else { + + $return = formatJSEND( "error", "Error selecting user information." ); + } + return( $return ); + } + + public static function is_admin() { + + $sql = "SELECT * FROM `users` WHERE `username`=? AND `access`=?;"; + $bind = "ss"; + $bind_variables = array( $_SESSION["user"], "admin" ); + $return = sql::sql( $sql, $bind, $bind_variables, formatJSEND( "error", "Error checking user acess." ) ); + + if( mysqli_num_rows( $return ) > 0 ) { + + return( true ); + } else { + + return( false ); + } + } + + public static function logout() { + + $sql = "UPDATE `users` SET `token`=? WHERE `username`=?;"; + $bind = "ss"; + $bind_variables = array( null, $_SESSION["user"] ); + $return = sql::sql( $sql, $bind, $bind_variables, formatJSEND( "error", "Error updating user information." ) ); + + try { + + $json = json_decode( $return, true ); + echo( $return ); + } catch( exception $e ) {} + + session_unset(); + session_destroy(); + session_start(); } ////////////////////////////////////////////////////////////////// @@ -220,6 +260,22 @@ class Common { } } + public static function return( $output, $action = "return" ) { + + switch( $action ) { + + case( "exit" ): + + exit( $output ); + break; + + case( "return" ): + + return( $output ); + break; + } + } + ////////////////////////////////////////////////////////////////// // Old Methods ////////////////////////////////////////////////////////////////// @@ -333,17 +389,20 @@ class Common { public static function checkSession() { - // Set any API keys - $api_keys = array(); - // Check API Key or Session Authentication - $key = ""; - if( isset( $_GET['key'] ) ) { + $pass = false; + $sql = "SELECT * FROM `users` WHERE `username`=? AND `token`=PASSWORD( ? );"; + $bind = "ss"; + $bind_variables = array( $_SESSION["user"], $_SESSION["token"] ); + $return = sql::sql( $sql, $bind, $bind_variables, formatJSEND( "error", "Error checking access." ) ); + + if( mysqli_num_rows( $return ) > 0 ) { - $key = $_GET['key']; + $pass = true; } - if( ! isset( $_SESSION['user'] ) && ! in_array( $key, $api_keys ) ) { + + if( ! $pass ) { - //exit('{"status":"error","message":"Authentication Error"}'); + logout(); exit( '{"status":"error","message":"Authentication Error"}' ); } } @@ -353,7 +412,7 @@ class Common { // Get JSON ////////////////////////////////////////////////////////////////// - public static function getJSON( $file, $namespace="" ) { + public static function getJSON( $file, $namespace = "" ) { $path = DATA . "/"; if( $namespace != "" ) { @@ -431,7 +490,7 @@ class Common { public static function checkAccess() { - return !file_exists( DATA . "/" . $_SESSION['user'] . '_acl.php' ); + return self::is_admin(); } ////////////////////////////////////////////////////////////////// @@ -509,6 +568,7 @@ class Common { // Wrapper for old method names ////////////////////////////////////////////////////////////////// +function is_admin() { Common::is_admin(); } function debug($message) { Common::debug($message); } function i18n($key, $args = array()) { echo Common::i18n($key, $args); } function get_i18n($key, $args = array()) { return Common::get_i18n($key, $args); } @@ -519,4 +579,6 @@ function formatJSEND($status,$data=false){ return Common::formatJSEND($status,$d function checkAccess() { return Common::checkAccess(); } function checkPath($path) { return Common::checkPath($path); } function isAvailable($func) { return Common::isAvailable($func); } +function logout() { return Common::logout(); } +function get_users() { return Common::get_users(); } ?> diff --git a/components/active/init.js b/components/active/init.js index 0455852..7e725ab 100755 --- a/components/active/init.js +++ b/components/active/init.js @@ -49,6 +49,12 @@ }, open: function(path, content, mtime, inBackground, focus) { + + //if( this. ) { + + + //} + if (focus === undefined) { focus = true; } diff --git a/components/autosave/init.js b/components/autosave/init.js index 40991dd..c0b6ef8 100755 --- a/components/autosave/init.js +++ b/components/autosave/init.js @@ -13,9 +13,9 @@ curpath = path.split('/').slice(0, -1).join('/')+'/'; // Instantiates plugin - $(function() { + $( function() { - amplify.subscribe('settings.changed', async function() { + amplify.subscribe( 'settings.changed', function() { codiad.auto_save.settings.autosave = codiad.settings.get_option( 'codiad.settings.autosave' ); codiad.auto_save.reload_interval(); @@ -25,7 +25,7 @@ }); codiad.auto_save = { - + // Allows relative `this.path` linkage auto_save_trigger: null, invalid_states: [ "", " ", null, undefined ], @@ -37,7 +37,7 @@ }, verbose: false, - init: async function() { + init: function() { codiad.auto_save.settings.autosave = codiad.settings.get_option( 'codiad.settings.autosave' ); @@ -48,31 +48,33 @@ window.clearInterval( this.auto_save_trigger ); if( codiad.auto_save.verbose ) { + console.log( 'Auto save disabled' ); } return; } - $(window).focus(function() { + $( window ).focus( function() { - //Turn auto save off if the user leaves the tab. - codiad.auto_save.settings.toggle = false; + //Turn auto save on if the user comes back the tab. + codiad.auto_save.settings.toggle = true; if( codiad.auto_save.verbose ) { + console.log( 'Auto save resumed' ); } }); - $(window).blur(function() { + $( window ).blur( function() { //Turn auto save off if the user leaves the tab. codiad.auto_save.settings.toggle = false; if( codiad.auto_save.verbose ) { + console.log( 'Auto save paused' ); } }); console.log( 'Auto save Enabled' ); - //let editor = document.getElementsByClassName( 'ace_content' )[0]; this.auto_save_trigger = setInterval( this.auto_save, 256 ); }, @@ -103,15 +105,22 @@ let content = codiad.editor.getContent(); codiad.active.save; - codiad.filemanager.saveFile(path, content, localStorage.removeItem(path), false); + codiad.filemanager.saveFile( path, content, localStorage.removeItem( path ), false ); var session = codiad.active.sessions[path]; if( typeof session != 'undefined' ) { + session.untainted = content; session.serverMTime = session.serverMTime; - if (session.listThumb) session.listThumb.removeClass('changed'); - if (session.tabThumb) session.tabThumb.removeClass('changed'); + if ( session.listThumb ) { + + session.listThumb.removeClass('changed'); + } + + if ( session.tabThumb ) { + + session.tabThumb.removeClass('changed'); + } } - this.saving = false; }, @@ -129,4 +138,4 @@ } } }; -})(this, jQuery); \ No newline at end of file +})( this, jQuery ); \ No newline at end of file diff --git a/components/filemanager/class.filemanager.php b/components/filemanager/class.filemanager.php index f589e35..aca0d68 100755 --- a/components/filemanager/class.filemanager.php +++ b/components/filemanager/class.filemanager.php @@ -424,19 +424,19 @@ class Filemanager extends Common { $files = array_diff( scandir( $path ), array( '.', '..' ) ); foreach ( $files as $file ) { - if ( is_link( "$path/$file" ) ) { + if ( is_link( $path . "/" . $file ) ) { if ( $follow ) { - rrmdir("$path/$file", $follow, false); + rrmdir( $path . "/" . $file, $follow, false); } - unlink( "$path/$file" ); - } elseif ( is_dir( "$path/$file" ) ) { + unlink( $path . "/" . $file ); + } elseif ( is_dir( $path . "/" . $file ) ) { - rrmdir( "$path/$file", $follow, false ); + rrmdir( $path . "/" . $file, $follow, false ); } else { - unlink( "$path/$file" ); + unlink( $path . "/" . $file ); } } if( $keep_parent === false ) { @@ -501,7 +501,7 @@ class Filemanager extends Common { } else { // Change content - if ($this->content || $this->patch) { + if ( $this->content || $this->patch ) { if ( $this->content == ' ' ) { diff --git a/components/project/class.project.php b/components/project/class.project.php index d2049e2..e97cdfb 100755 --- a/components/project/class.project.php +++ b/components/project/class.project.php @@ -22,6 +22,7 @@ class Project extends Common { public $no_return = false; public $assigned = false; public $command_exec = ''; + public $public_project = false; ////////////////////////////////////////////////////////////////// // METHODS @@ -44,12 +45,12 @@ class Project extends Common { public function add_project( $project_name, $project_path, $owner = null ) { - if( $owner == null ) { - - $owner = $_SESSION["user"]; - } else { + if( $this->public_project ) { $owner = 'nobody'; + } else { + + $owner = $_SESSION["user"]; } $sql = "INSERT INTO `projects`( `name`, `path`, `owner` ) VALUES ( ?, ?, ? );"; @@ -60,30 +61,103 @@ class Project extends Common { return( $return ); } - public function delete_project( $project_name, $project_path, $owner = null ) { + public function check_owner( $path = null, $exclude_public = false ) { - if( $owner == null ) { + if( $path === null ) { - $owner = $_SESSION["user"]; + $path = $this->path; + } + $sql = "SELECT `owner` FROM `projects` WHERE `path`=?"; + $bind = "s"; + $bind_variables = array( $path ); + $result = sql::sql( $sql, $bind, $bind_variables, formatJSEND( "error", "Error fetching projects." ) ); + $return = false; + + if( mysqli_num_rows( $result ) > 0 ) { + + $owner = mysqli_fetch_assoc( $result )["owner"]; + if( $exclude_public ) { + + if( $owner == $_SESSION["user"] ) { + + $return = true; + } + } else { + + if( $owner == $_SESSION["user"] || $owner == 'nobody' ) { + + $return = true; + } + } + } + return( $return ); + } + + public function get_access( $path = null ) { + + if( $path === null ) { + + $path = $this->path; + } + $sql = "SELECT `access` FROM `projects` WHERE `path`=?"; + $bind = "s"; + $bind_variables = array( $path ); + $return = sql::sql( $sql, $bind, $bind_variables, formatJSEND( "error", "Error fetching project information." ) ); + + if( mysqli_num_rows( $return ) > 0 ) { + + $return = mysqli_fetch_assoc( $return )["access"]; } else { - $owner = 'nobody'; + $return = formatJSEND( "error", "Error fetching project info." ); } - $owner = $_SESSION["user"]; - $sql = "DELETE FROM `projects` WHERE `name`=? AND `path`=? AND ( `owner`=? OR `owner`='nobody' );"; - $bind = "sss"; - $bind_variables = array( $project_name, $project_path, $owner ); - $return = sql::sql( $sql, $bind, $bind_variables, formatJSEND( "error", "Error deleting project $project_name." ) ); + return( $return ); + } + + public function get_owner( $path = null ) { - try { + if( $path === null ) { - $json = json_decode( $return, true ); - exit( $return ); - } catch( exception $e ) { - - exit( formatJSEND( "success", "Successfully deleted project $project_name." ) ); + $path = $this->path; } + $sql = "SELECT `owner` FROM `projects` WHERE `path`=?"; + $bind = "s"; + $bind_variables = array( $path ); + $return = sql::sql( $sql, $bind, $bind_variables, formatJSEND( "error", "Error fetching projects." ) ); + + if( mysqli_num_rows( $return ) > 0 ) { + + $return = mysqli_fetch_assoc( $return )["owner"]; + } else { + + $return = formatJSEND( "error", "Error fetching project info." ); + } + + return( $return ); + } + + public function get_project( $project = null ) { + + if( $project === null ) { + + $project = $this->path; + } + + $sql = "SELECT * FROM `projects` WHERE `path`=? AND ( `owner`=? OR `owner`='nobody' ) ORDER BY `name`;"; + $bind = "ss"; + $bind_variables = array( $project, $_SESSION["user"] ); + $return = sql::sql( $sql, $bind, $bind_variables, formatJSEND( "error", "Error fetching projects." ) ); + + if( mysqli_num_rows( $return ) > 0 ) { + + $return = mysqli_fetch_all( $return, MYSQLI_ASSOC )[0]; + } else { + + $return = formatJSEND( "error", "Error fetching projects." ); + } + + return( $return ); } public function get_projects() { @@ -169,18 +243,20 @@ class Project extends Common { public function Open() { - $pass = false; - foreach ( $this->projects as $project => $data ) { - - if ( $data['path'] == $this->path ) { - - $pass = true; - $this->name = $data['name']; - $_SESSION['project'] = $data['path']; - } - } - if ( $pass ) { + $sql = "SELECT * FROM `projects` WHERE `path`=? AND ( `owner`=? OR `owner`='nobody' );"; + $bind = "ss"; + $bind_variables = array( $this->path, $_SESSION["user"] ); + $return = sql::sql( $sql, $bind, $bind_variables, formatJSEND( "error", "Error fetching projects." ) ); + + if( mysqli_num_rows( $return ) > 0 ) { + $return = mysqli_fetch_assoc( $return ); + $sql = "UPDATE `users` SET `project`=? WHERE `username`=?;"; + $bind = "ss"; + $bind_variables = array( $this->path, $_SESSION["user"] ); + sql::sql( $sql, $bind, $bind_variables, formatJSEND( "error", "Error fetching projects." ) ); + $this->name = $return['name']; + $_SESSION['project'] = $return['path']; echo formatJSEND( "success", array( "name" => $this->name, "path" => $this->path ) ); } else { @@ -204,6 +280,11 @@ class Project extends Common { } if ( $this->path != '' ) { + if( ! $this->public_project ) { + + $this->path = $_SESSION["user"] . '/' . $this->path; + } + $pass = $this->checkDuplicate(); if ( $pass ) { @@ -312,16 +393,17 @@ class Project extends Common { public function Delete() { - $revised_array = array(); - foreach ( $this->projects as $project => $data ) { + $sql = "DELETE FROM `projects` WHERE `path`=? AND ( `owner`=? OR `owner`='nobody' );"; + $bind = "ss"; + $bind_variables = array( $this->path, $_SESSION["user"] ); + $return = sql::sql( $sql, $bind, $bind_variables, formatJSEND( "error", "Error deleting project $project_name." ) ); + + if( sql::check_sql_error( $return ) ) { - if ( $data['path'] != $this->path ) { - - $revised_array[] = array( "name" => $data['name'], "path" => $data['path'] ); - } else { - - $this->delete_project( $data['name'], $data['path'] ); - } + echo( formatJSEND( "success", "Successfully deleted $project_name." ) ); + } else { + + echo $return; } } diff --git a/components/project/controller.php b/components/project/controller.php index 0ae0f32..491f043 100755 --- a/components/project/controller.php +++ b/components/project/controller.php @@ -18,97 +18,149 @@ checkSession(); $Project = new Project(); -////////////////////////////////////////////////////////////////// -// Get Current Project -////////////////////////////////////////////////////////////////// - -$no_return = false; -if (isset($_GET['no_return'])) { -$no_return = true; -} - -if ($_GET['action']=='get_current') { - -if ( ! isset($_SESSION['project'])) { -// Load default/first project -if ($no_return) { -$Project->no_return = true; -} -$Project->GetFirst(); -} else { -// Load current -$Project->path = $_SESSION['project']; -$project_name = $Project->GetName(); -if (!$no_return) { -echo formatJSEND("success", array("name"=>$project_name,"path"=>$_SESSION['project'])); -} -} -} - -////////////////////////////////////////////////////////////////// -// Open Project -////////////////////////////////////////////////////////////////// - -if ($_GET['action']=='open') { -if (!checkPath($_GET['path'])) { -die(formatJSEND("error", "No Access to path " . $_GET['path'])); -} -$Project->path = $_GET['path']; -$Project->Open(); -} - ////////////////////////////////////////////////////////////////// // Create Project ////////////////////////////////////////////////////////////////// -if ($_GET['action']=='create') { -if (checkAccess()) { -$Project->name = $_GET['project_name']; -if ($_GET['project_path'] != '') { -$Project->path = $_GET['project_path']; -} else { -$Project->path = $_GET['project_name']; -} -// Git Clone? -if (!empty($_GET['git_repo'])) { -$Project->gitrepo = $_GET['git_repo']; -$Project->gitbranch = $_GET['git_branch']; -} -$Project->Create(); -} -} - -////////////////////////////////////////////////////////////////// -// Rename Project -////////////////////////////////////////////////////////////////// - -if ($_GET['action']=='rename') { -if (!checkPath($_GET['project_path'])) { -die(formatJSEND("error", "No Access")); -} -$Project->path = $_GET['project_path']; -$Project->Rename(); -} - -////////////////////////////////////////////////////////////////// -// Delete Project -////////////////////////////////////////////////////////////////// - -if ($_GET['action']=='delete') { -if (checkAccess()) { -$Project->path = $_GET['project_path']; -$Project->Delete(); -} +if( $_GET['action'] == 'create' ) { + + $Project->name = $_GET['project_name']; + + if( $_GET['public_project'] == 'true' ) { + + $Project->public_project = true; + } + + if( $_GET['project_path'] != '' ) { + + $Project->path = $_GET['project_path']; + } else { + + $Project->path = $_GET['project_name']; + } + // Git Clone? + if( ! empty( $_GET['git_repo'] ) ) { + + $Project->gitrepo = $_GET['git_repo']; + $Project->gitbranch = $_GET['git_branch']; + } + $Project->Create(); } ////////////////////////////////////////////////////////////////// // Return Current ////////////////////////////////////////////////////////////////// -if ($_GET['action']=='current') { -if (isset($_SESSION['project'])) { -echo formatJSEND("success", $_SESSION['project']); -} else { -echo formatJSEND("error", "No Project Returned"); +if( $_GET['action'] == 'current' ) { + + if( isset( $_SESSION['project'] ) ) { + + echo formatJSEND( "success", $_SESSION['project'] ); + } else { + + echo formatJSEND( "error", "No Project Returned" ); + } } + +////////////////////////////////////////////////////////////////// +// Delete Project +////////////////////////////////////////////////////////////////// + +if( $_GET['action'] == 'delete' ) { + + if( checkPath( $_GET['project_path'] ) ) { + + $Project->path = $_GET['project_path']; + $Project->Delete(); + } } + +////////////////////////////////////////////////////////////////// +// Get Project Access +////////////////////////////////////////////////////////////////// + +if( $_GET['action'] == 'get_access' ) { + + $Project->path = $_GET['project_path']; + $access = $Project->get_access( $_GET['project_path'] ); + echo formatJSEND( "success", $access ); +} + +////////////////////////////////////////////////////////////////// +// Get Current Project +////////////////////////////////////////////////////////////////// + +$no_return = false; +if( isset( $_GET['no_return'] ) ) { + + $no_return = true; +} + +if( $_GET['action'] == 'get_current' ) { + + if( ! isset( $_SESSION['project'] ) ) { + + // Load default/first project + if( $no_return ) { + + $Project->no_return = true; + } + $Project->GetFirst(); + } else { + + // Load current + $Project->path = $_SESSION['project']; + $project_name = $Project->GetName(); + if( ! $no_return ) { + + echo formatJSEND( "success", array( "name" => $project_name, "path" => $_SESSION['project'] ) ); + } + } +} + +////////////////////////////////////////////////////////////////// +// Check Project Owner +////////////////////////////////////////////////////////////////// + +if( $_GET['action'] == 'get_owner' ) { + + $Project->path = $_GET['project_path']; + $owner = $Project->get_owner(); + try { + + $return = json_decode( $owner ); + exit( formatJSEND( "error", null ) ); + } catch( exception $e ) { + + exit( formatJSEND( "success", array( "owner" => $owner ) ) ); + } +} + +////////////////////////////////////////////////////////////////// +// Open Project +////////////////////////////////////////////////////////////////// + +if( $_GET['action'] == 'open' ) { + + if( ! checkPath( $_GET['path'] ) ) { + + die( formatJSEND( "error", "No Access to path " . $_GET['path'] ) ); + } + $Project->path = $_GET['path']; + $Project->Open(); +} + +////////////////////////////////////////////////////////////////// +// Rename Project +////////////////////////////////////////////////////////////////// + +if( $_GET['action'] == 'rename' ) { + + if( ! checkPath( $_GET['project_path'] ) ) { + + die( formatJSEND( "error", "No Access" ) ); + } + $Project->path = $_GET['project_path']; + $Project->Rename(); +} + diff --git a/components/project/dialog.php b/components/project/dialog.php index f95ab15..1b019c1 100755 --- a/components/project/dialog.php +++ b/components/project/dialog.php @@ -65,7 +65,8 @@ switch( $_GET['action'] ) {