diff --git a/common.php b/common.php index f4aab00..1e6270b 100755 --- a/common.php +++ b/common.php @@ -157,10 +157,25 @@ class Common { self::return( $return, $action ); } + public static function get_user_id( $username ) { + + global $sql; + $user_id = false; + $query = "SELECT id FROM users WHERE username = ? LIMIT 1;"; + $bind_variables = array( $username ); + $return = $sql->query( $query, $bind_variables, array(), "fetch" ); + + if( ! empty( $return ) ) { + + $user_id = $return["id"]; + } + return $user_id; + } + public static function get_users( $return = "return", $exclude_current = false ) { global $sql; - $query = "SELECT username FROM users"; + $query = "SELECT * FROM users"; $bind = ""; $bind_variables = array(); @@ -172,25 +187,19 @@ class Common { } $result = $sql->query( $query, $bind_variables, formatJSEND( "error", "Error checking users." ) ); - $user_list = array(); - - foreach( $result as $row ) { - - array_push( $user_list, $row["username"] ); - } - + if( ! empty( $result ) ) { switch( $return ) { case( "json" ): - $return = json_encode( $user_list ); + $return = json_encode( $result ); break; case( "return" ): - $return = $user_list; + $return = $result; break; } } else { @@ -615,19 +624,20 @@ class Common { // Wrapper for old method names ////////////////////////////////////////////////////////////////// -function is_admin() { return 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); } -function checkSession(){ Common::checkSession(); } -function getJSON($file,$namespace=""){ return Common::getJSON($file,$namespace); } -function saveJSON($file,$data,$namespace=""){ Common::saveJSON($file,$data,$namespace); } -function formatJSEND($status,$data=false){ return Common::formatJSEND($status,$data); } 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 checkPath( $path ) { return Common::checkPath($path); } +function checkSession() { Common::checkSession(); } +function debug( $message ) { Common::debug( $message ); } +function formatJSEND( $status, $data=false ){ return Common::formatJSEND($status,$data); } +function get_i18n( $key, $args = array() ) { return Common::get_i18n($key, $args); } +function get_user_id( $username ) { return Common::get_user_id( $username ); } function get_users( $return = "return", $exclude_current = false ) { return Common::get_users( $return, $exclude_current ); } -function search_users( $username, $return = "return", $exclude_current = false ) { return Common::search_users( $username, $return, $exclude_current ); } function get_version() { return Common::get_version(); } +function getJSON( $file,$namespace=""){ return Common::getJSON( $file, $namespace ); } +function i18n( $key, $args = array() ) { echo Common::i18n( $key, $args ); } +function is_admin() { return Common::is_admin(); } +function isAvailable( $func ) { return Common::isAvailable( $func ); } +function logout() { return Common::logout(); } +function saveJSON( $file, $data, $namespace="" ){ Common::saveJSON( $file, $data, $namespace ); } +function search_users( $username, $return = "return", $exclude_current = false ) { return Common::search_users( $username, $return, $exclude_current ); } ?> diff --git a/components/active/class.active.php b/components/active/class.active.php index d3e0204..dac9313 100755 --- a/components/active/class.active.php +++ b/components/active/class.active.php @@ -31,6 +31,14 @@ class Active extends Common { public function __construct() { } + public static function remove( $path ) { + + global $sql; + $query = "DELETE FROM active WHERE path=? AND username=?;"; + $bind_variables = array( $path, $_SESSION["user"] ); + $return = $sql->query( $query, $bind_variables, 0, "rowCount" ); + } + ////////////////////////////////////////////////////////////////// // List User's Active Files ////////////////////////////////////////////////////////////////// @@ -38,14 +46,14 @@ class Active extends Common { public function ListActive() { global $sql; - $query = "SELECT path,position,focused FROM active WHERE username=?"; + $query = "SELECT path, position, focused FROM active WHERE username=?"; $bind_variables = array( $this->username ); $result = $sql->query( $query, $bind_variables, array() ); $tainted = false; $root = WORKSPACE; $active_list = $result; - if( ! empty( $return ) ) { + if( ! empty( $result ) ) { foreach ( $result as $id => $data ) { @@ -57,20 +65,14 @@ class Active extends Common { $root = $root.'/'; } - if ( ! file_exists( $root . $data['path'] ) ) { + if ( ! is_file( $root . $data['path'] ) ) { - $tainted = true; + self::remove( $data['path'] ); unset( $active_list[$id] ); } } } - - if( $tainted ) { - - $this->update_active( $active_list ); - } - - echo formatJSEND( "success", $active_list ); + exit( formatJSEND( "success", $active_list ) ); } ////////////////////////////////////////////////////////////////// @@ -140,23 +142,6 @@ class Active extends Common { } } - ////////////////////////////////////////////////////////////////// - // Remove File - ////////////////////////////////////////////////////////////////// - - public function Remove() { - - global $sql; - $query = "DELETE FROM active WHERE path=? AND username=?;"; - $bind_variables = array( $this->path, $this->username ); - $return = $sql->query( $query, $bind_variables, 0, "rowCount" ); - - if( $return > 0 ) { - - echo formatJSEND( "success" ); - } - } - ////////////////////////////////////////////////////////////////// // Remove All Files ////////////////////////////////////////////////////////////////// diff --git a/components/active/controller.php b/components/active/controller.php index a5fa7ac..0d1f9ff 100755 --- a/components/active/controller.php +++ b/components/active/controller.php @@ -1,94 +1,101 @@ username = $_SESSION['user']; - $Active->ListActive(); -} - - ////////////////////////////////////////////////////////////////// - // Add active record - ////////////////////////////////////////////////////////////////// - -if ($_GET['action']=='add') { - $Active->username = $_SESSION['user']; - $Active->path = $_GET['path']; - $Active->Add(); -} - - ////////////////////////////////////////////////////////////////// - // Rename - ////////////////////////////////////////////////////////////////// - -if ($_GET['action']=='rename') { - $Active->username = $_SESSION['user']; - $Active->path = $_GET['old_path']; - $Active->new_path = $_GET['new_path']; - $Active->Rename(); -} - - ////////////////////////////////////////////////////////////////// - // Check if file is active - ////////////////////////////////////////////////////////////////// - -if ($_GET['action']=='check') { - $Active->username = $_SESSION['user']; - $Active->path = $_GET['path']; - $Active->Check(); -} - - ////////////////////////////////////////////////////////////////// - // Remove active record - ////////////////////////////////////////////////////////////////// - -if ($_GET['action']=='remove') { - $Active->username = $_SESSION['user']; - $Active->path = $_GET['path']; - $Active->Remove(); -} - - ////////////////////////////////////////////////////////////////// - // Remove all active record - ////////////////////////////////////////////////////////////////// - -if ($_GET['action']=='removeall') { - $Active->username = $_SESSION['user']; - $Active->RemoveAll(); -} - - ////////////////////////////////////////////////////////////////// - // Mark file as focused - ////////////////////////////////////////////////////////////////// - -if ($_GET['action']=='focused') { - $Active->username = $_SESSION['user']; - $Active->path = $_GET['path']; - $Active->MarkFileAsFocused(); -} - -if ($_GET['action']=='save_positions') { +if( $_GET['action'] == 'list' ) { - ignore_user_abort( true ); - $Active->username = $_SESSION['user']; - $Active->savePositions( $_POST["positions"] ); + $Active->username = $_SESSION['user']; + $Active->ListActive(); +} + +////////////////////////////////////////////////////////////////// +// Add active record +////////////////////////////////////////////////////////////////// + +if ( $_GET['action'] == 'add' ) { + + $Active->username = $_SESSION['user']; + $Active->path = $_GET['path']; + $Active->Add(); +} + +////////////////////////////////////////////////////////////////// +// Rename +////////////////////////////////////////////////////////////////// + +if ( $_GET['action'] == 'rename' ) { + + $Active->username = $_SESSION['user']; + $Active->path = $_GET['old_path']; + $Active->new_path = $_GET['new_path']; + $Active->Rename(); +} + +////////////////////////////////////////////////////////////////// +// Check if file is active +////////////////////////////////////////////////////////////////// + +if ( $_GET['action'] == 'check' ) { + + $Active->username = $_SESSION['user']; + $Active->path = $_GET['path']; + $Active->Check(); +} + +////////////////////////////////////////////////////////////////// +// Remove active record +////////////////////////////////////////////////////////////////// + +if ( $_GET['action'] == 'remove' ) { + + $Active->username = $_SESSION['user']; + $Active->path = $_GET['path']; + $Active->remove( $Active->path ); +} + +////////////////////////////////////////////////////////////////// +// Remove all active record +////////////////////////////////////////////////////////////////// + +if( $_GET['action'] == 'removeall' ) { + + $Active->username = $_SESSION['user']; + $Active->RemoveAll(); +} + +////////////////////////////////////////////////////////////////// +// Mark file as focused +////////////////////////////////////////////////////////////////// + +if( $_GET['action'] == 'focused' ) { + + $Active->username = $_SESSION['user']; + $Active->path = $_GET['path']; + $Active->MarkFileAsFocused(); +} + +if( $_GET['action'] == 'save_positions' ) { + + ignore_user_abort( true ); + $Active->username = $_SESSION['user']; + $Active->savePositions( $_POST["positions"] ); } diff --git a/components/active/init.js b/components/active/init.js index 1c5a035..a51a404 100755 --- a/components/active/init.js +++ b/components/active/init.js @@ -51,12 +51,8 @@ return !!this.sessions[path]; }, - open: function( path, content, mtime, inBackground, focus ) { + open: function( path, content, mtime, inBackground, focus, read_only=false ) { - //if( this. ) { - - - //} /* Notify listeners. */ amplify.publish( 'active.onFileWillOpen', { path: path, @@ -64,12 +60,14 @@ }); if( focus === undefined ) { + focus = true; } var _this = this; if( this.isOpen( path ) ) { + if( focus ) this.focus( path ); return; } @@ -98,6 +96,8 @@ session.serverMTime = mtime; _this.sessions[path] = session; session.untainted = content.slice( 0 ); + session.read_only = read_only; + if( !inBackground && focus ) { codiad.editor.setSession( session ); } @@ -275,6 +275,7 @@ // Open saved-state active files on load $.get( _this.controller + '?action=list', function( data ) { + console.log( data ); var listResponse = codiad.jsend.parse( data ); if( listResponse !== null ) { $.each( listResponse, function( index, data ) { diff --git a/components/editor/init.js b/components/editor/init.js index ba78c8b..d5d6e01 100755 --- a/components/editor/init.js +++ b/components/editor/init.js @@ -390,11 +390,16 @@ this.setTabSize( this.settings.tabSize, i ); this.setSoftTabs( this.settings.softTabs, i ); this.setOverScroll( this.settings.overScroll, i ); - i.setOptions( { + i.setOptions({ enableBasicAutocompletion: true, enableSnippets: true, enableLiveAutocompletion: this.settings.autocomplete }); + + if( i.getSession().read_only ) { + + i.setReadOnly( true ); + } }, ////////////////////////////////////////////////////////////////// @@ -718,11 +723,15 @@ ///////////////////////////////////////////////////////////////// setSession: function( session, i ) { + i = i || this.getActive(); if( !this.isOpen( session ) ) { + if( !i ) { + i = this.addInstance( session ); } else { + i.setSession( session ); } } else { diff --git a/components/filemanager/class.filemanager.php b/components/filemanager/class.filemanager.php index 5e9fc87..8ff5239 100755 --- a/components/filemanager/class.filemanager.php +++ b/components/filemanager/class.filemanager.php @@ -15,6 +15,7 @@ class Filemanager extends Common { // PROPERTIES ////////////////////////////////////////////////////////////////// + public $access = 0; public $root = ""; public $project = ""; public $rel_path = ""; @@ -351,8 +352,8 @@ class Filemanager extends Common { if ( is_file( $this->path ) ) { - $output = file_get_contents($this->path); - + $output = file_get_contents( $this->path ); + if ( extension_loaded( 'mbstring' ) ) { if ( ! mb_check_encoding( $output, 'UTF-8' ) ) { @@ -371,6 +372,8 @@ class Filemanager extends Common { $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 ) ); } else { $this->status = "error"; @@ -562,60 +565,66 @@ class Filemanager extends Common { $this->respond(); return; } - echo var_dump( Permissions::has_write( $this->path ) ); - if ( is_file( $this->path ) && Permissions::has_write( $this->path ) ) { + + if ( is_file( $this->path ) ) { - $serverMTime = filemtime( $this->path ); - $fileContents = file_get_contents( $this->path ); - - if ( $this->patch && $this->mtime != $serverMTime ) { + if( Permissions::has_write( $this->path ) ) { - $this->status = "error"; - $this->message = "Client is out of sync"; - //DEBUG : file_put_contents($this->path.".conflict", "SERVER MTIME :".$serverMTime.", CLIENT MTIME :".$this->mtime); - $this->respond(); - return; - } elseif ( strlen( trim( $this->patch ) ) == 0 && ! $this->content ) { + $serverMTime = filemtime( $this->path ); + $fileContents = file_get_contents( $this->path ); - // Do nothing if the patch is empty and there is no content - $this->status = "success"; - $this->data = '"mtime":' . $serverMTime; - $this->respond(); - return; - } - - if ( $file = fopen( $this->path, 'w' ) ) { - - if ( $this->patch ) { - - $dmp = new diff_match_patch(); - $p = $dmp->patch_apply( $dmp->patch_fromText( $this->patch ), $fileContents ); - $this->content = $p[0]; - //DEBUG : file_put_contents($this->path.".orig",$fileContents ); - //DEBUG : file_put_contents($this->path.".patch", $this->patch); - } - - if ( fwrite( $file, $this->content ) === false ) { + if ( $this->patch && $this->mtime != $serverMTime ) { $this->status = "error"; - $this->message = "could not write to file"; - } else { + $this->message = "Client is out of sync"; + //DEBUG : file_put_contents($this->path.".conflict", "SERVER MTIME :".$serverMTime.", CLIENT MTIME :".$this->mtime); + $this->respond(); + return; + } elseif ( strlen( trim( $this->patch ) ) == 0 && ! $this->content ) { - // Unless stat cache is cleared the pre-cached mtime will be - // returned instead of new modification time after editing - // the file. - clearstatcache(); - $this->data = '"mtime":'.filemtime( $this->path ); + // Do nothing if the patch is empty and there is no content $this->status = "success"; + $this->data = '"mtime":' . $serverMTime; + $this->respond(); + return; } - fclose( $file ); + if ( $file = fopen( $this->path, 'w' ) ) { + + if ( $this->patch ) { + + $dmp = new diff_match_patch(); + $p = $dmp->patch_apply( $dmp->patch_fromText( $this->patch ), $fileContents ); + $this->content = $p[0]; + //DEBUG : file_put_contents($this->path.".orig",$fileContents ); + //DEBUG : file_put_contents($this->path.".patch", $this->patch); + } + + if ( fwrite( $file, $this->content ) === false ) { + + $this->status = "error"; + $this->message = "could not write to file"; + } else { + + // Unless stat cache is cleared the pre-cached mtime will be + // returned instead of new modification time after editing + // the file. + clearstatcache(); + $this->data = '"mtime":'.filemtime( $this->path ); + $this->status = "success"; + } + + fclose( $file ); + } else { + + $this->status = "error"; + $this->message = "Cannot Write to File"; + } } else { $this->status = "error"; - $this->message = "Cannot Write to File"; + $this->message = "Write access is denied."; } - } else { $this->status = "error"; diff --git a/components/filemanager/controller.php b/components/filemanager/controller.php index 61b9304..c474655 100755 --- a/components/filemanager/controller.php +++ b/components/filemanager/controller.php @@ -39,9 +39,11 @@ if (!isset($_SESSION['project'])) { // Security Check ////////////////////////////////////////////////////////////////// -if ( ! Permissions::has_read( $_GET['path'] ) ) { +$access = Permissions::get_access( $_GET['path'] ); + +if ( ! Permissions::check_access( "read", $access ) ) { - die('{"status":"error","message":"Invalid Path"}'); + die( '{"status":"error","message":"Invalid access to ' . $_GET['path'] . '."}' ); } ////////////////////////////////////////////////////////////////// @@ -56,6 +58,7 @@ if ( ! Permissions::has_read( $_GET['path'] ) ) { $Filemanager = new Filemanager($_GET, $_POST, $_FILES); $Filemanager->project = @$_SESSION['project']['path']; + $Filemanager->access = $access; switch ($action) { case 'index': diff --git a/components/filemanager/init.js b/components/filemanager/init.js index ef867a6..a380476 100755 --- a/components/filemanager/init.js +++ b/components/filemanager/init.js @@ -459,35 +459,41 @@ // Open File ////////////////////////////////////////////////////////////////// - openFile: function( path, focus ) { + openFile: function( path, focus=true ) { /* Notify listeners. */ amplify.publish( 'filemanager.onFileWillOpen', { path: path }); - if( focus === undefined ) { - focus = true; - } var node = $( '#file-manager a[data-path="' + path + '"]' ); var ext = this.getExtension( path ); + if( $.inArray( ext.toLowerCase(), this.noOpen ) < 0 ) { + node.addClass( 'loading' ); $.get( this.controller + '?action=open&path=' + encodeURIComponent( path ), function( data ) { + var openResponse = codiad.jsend.parse( data ); if( openResponse != 'error' ) { + node.removeClass( 'loading' ); - codiad.active.open( path, openResponse.content, openResponse.mtime, false, focus ); + codiad.active.open( path, openResponse.content, openResponse.mtime, false, focus, openResponse.read_only ); } }); } else { - if( !codiad.project.isAbsPath( path ) ) { + + if( ! codiad.project.isAbsPath( path ) ) { + if( $.inArray( ext.toLowerCase(), this.noBrowser ) < 0 ) { + this.download( path ); } else { + this.openInModal( path ); } } else { + codiad.message.error( i18n( 'Unable to open file in Browser while using absolute path.' ) ); } } @@ -583,21 +589,26 @@ path: path }); }, - saveModifications: function( path, data, callbacks, save = true ) { + saveModifications: function( path, data, callbacks, messages = true ) { callbacks = callbacks || {}; let _this = this, action; var notifySaveErr = function() { + codiad.message.error( i18n( 'File could not be saved' ) ); if( typeof callbacks.error === 'function' ) { + var context = callbacks.context || _this; callbacks.error.apply( context, [data] ); } } + $.post( this.controller + '?action=modify&path=' + encodeURIComponent( path ), data, function( resp ) { + + console.log( resp ); resp = $.parseJSON( resp ); if( resp.status == 'success' ) { - if( save === true ) { + if( messages === true ) { codiad.message.success( i18n( 'File saved' ) ); } if( typeof callbacks.success === 'function' ) { @@ -621,8 +632,11 @@ session.serverMTime = null; session.untainted = null; } - } else codiad.message.error( i18n( 'File could not be saved' ) ); + //} else codiad.message.error( i18n( 'File could not be saved' ) ); + } else codiad.message.error( i18n( resp.message ) ); + if( typeof callbacks.error === 'function' ) { + var context = callbacks.context || _this; callbacks.error.apply( context, [resp.data] ); } @@ -633,10 +647,10 @@ // Save file ////////////////////////////////////////////////////////////////// - saveFile: function( path, content, callbacks, save = true ) { + saveFile: function( path, content, callbacks, messages = true ) { this.saveModifications( path, { content: content - }, callbacks, save ); + }, callbacks, messages ); }, savePatch: function( path, patch, mtime, callbacks, alerts ) { diff --git a/components/permissions/class.permissions.php b/components/permissions/class.permissions.php index b3ce214..a4fa5c6 100644 --- a/components/permissions/class.permissions.php +++ b/components/permissions/class.permissions.php @@ -5,17 +5,22 @@ * [root]/license.txt for more. This information must remain intact. */ +ini_set('display_errors', 1); +ini_set('display_startup_errors', 1); +error_reporting(E_ALL); + class Permissions { const LEVELS = array( - "admin" => 0, - "owner" => 1, - "manager" => 2, - "delete" => 3, + "none" => 0, + "read" => 1, + "write" => 2, "create" => 4, - "write" => 5, - "read" => 6, + "delete" => 8, + "manager" => 16, + "owner" => 32, + "admin" => 64, ); function __construct() { @@ -23,75 +28,106 @@ class Permissions { } - public static function check_path( $level, $path ) { + public static function check_access( $level, $user_level ) { - $project_path = $_SESSION["project"]; - $project_path = rtrim( $project_path, '/' ) . '/'; + if( ! is_integer( $level ) ) { + + if( in_array( $level, array_keys( self::LEVELS ) ) ) { + + $level = self::LEVELS[$level]; + } else { + + exit( formatJSEND( "error", "Access Level does not exist." ) ); + } + } + + return ( $user_level >= $level ); + } + + public static function check_path( $level, $path ) { if( ! in_array( $level, array_keys( self::LEVELS ) ) ) { - exit( Common::formatJSEND( "error", "Access Level does not exist." ) ); + exit( formatJSEND( "error", "Access Level does not exist." ) ); } - if( strpos( $path, $project_path ) === 0 ) { + $pass = false; + $user_level = self::get_access( $path ); + + if( $user_level >= self::LEVELS[$level] ) { - exit( Common::formatJSEND( "error", "Error with path." ) ); + $pass = true; } + return( $pass ); + } + + public static function get_access( $path ) { global $sql; - $pass = false; - //$query = "SELECT * FROM projects WHERE LOCATE( path, ? ) > 0 LIMIT 1;"; - //$bind_variables = array( $path ); - //$result = $sql->query( $query, $bind_variables, array() )[0]; - /*$result = $sql->select( - "projects", - array(), - array( - array( - "find", - $path, - array( - "more than", - 0 - ) - ), - array( - "limit", - 1 - ) - ) - );*/ + $full_path = Common::isAbsPath( $path ) ? $path : WORKSPACE . "/{$path}"; + $access = 0; + //$query = "SELECT id, path, owner FROM projects WHERE path LIKE ?;"; + //$bind_variables = array( "{$path}%" ); + $query = "SELECT id, path, owner FROM projects;"; + $bind_variables = array(); + $projects = $sql->query( $query, $bind_variables, array() ); - $query = "SELECT * FROM projects WHERE path=? LIMIT 1;"; - $bind_variables = array( $_SESSION["project"] ); - $result = $sql->query( $query, $bind_variables, array() ); - - if( ! empty( $result ) ) { + if( ! empty( $projects ) ) { - $result = $result[0]; - $users = $sql->query( "SELECT * FOM access WHERE project = ? AND user = ? LIMIT 1", array( $result["id"], $_SESSION["user_id"] ), array() ); - - if( $result["owner"] == 'nobody' ) { + foreach( $projects as $row => $data ) { - $pass = true; - } elseif( $result["owner"] == $_SESSION["user"] ) { + $full_project_path = Common::isAbsPath( $data["path"] ) ? $data["path"] : WORKSPACE . "/{$data["path"]}"; + $path_postition = strpos( $full_path, $full_project_path ); - $pass = true; - } elseif( ! empty( $users ) ) { - - //Only allow the owner to delete the root dir / project - if( $path == $result["path"] && self::LEVELS[$level] == self::LEVELS["delete"] ) { + if( $path_postition === false ) { - $level = "owner"; + continue; } - if( self::LEVELS[$level] >= $users_access ) { + if( $data["owner"] == 'nobody' ) { - $pass = true; + $access = self::LEVELS["owner"]; + } elseif( $data["owner"] == $_SESSION["user"] ) { + + $access = self::LEVELS["owner"]; + } else { + + $user = $sql->query( "SELECT * FROM access WHERE project = ? AND user = ? LIMIT 1", array( $data["id"], $_SESSION["user_id"] ), array(), "fetch" ); + + if( ! empty( $user ) ) { + + $access = $user["level"]; + } + } + + //echo var_dump( $full_path, $full_project_path, $path_postition, $user["level"], $pass ); + if( $access > 0 ) { + + break; } } } - return( $pass ); + return $access; + } + + public static function get_level( $i ) { + + $level = 0; + if( is_integer( $i ) ) { + + $level = array_search( $i, self::LEVELS ); + } else { + + if( in_array( $i, array_keys( self::LEVELS ) ) ) { + + $level = self::LEVELS[$i]; + } else { + + exit( formatJSEND( "error", "Access Level does not exist." ) ); + } + } + + return $level; } public static function has_owner( $path ) { diff --git a/components/project/class.project.php b/components/project/class.project.php index 2a39f1d..df1b538 100755 --- a/components/project/class.project.php +++ b/components/project/class.project.php @@ -14,7 +14,7 @@ class Project extends Common { // PROPERTIES ////////////////////////////////////////////////////////////////// - public $access = 100; + public $access = Permissions::LEVELS["read"]; public $name = ''; public $path = ''; public $gitrepo = false; @@ -68,53 +68,50 @@ class Project extends Common { public function add_user() { global $sql; - $query = "SELECT access FROM projects WHERE path=? AND owner=?"; + $query = "SELECT * FROM projects WHERE path=? AND owner=? LIMIT 1"; $bind_variables = array( $this->path, $_SESSION["user"] ); - $result = $sql->query( $query, $bind_variables, array() )[0]; + $project = $sql->query( $query, $bind_variables, array(), "fetch" ); - if( ! empty( $result ) ) { + if( empty( $project ) ) { - $access = json_decode( $result["access"] ); + exit( formatJSEND( "error", "Error fetching projects." ) ); + } + + $user_id = get_user_id( $this->user ); + + if( $user_id === false ) { - if( is_array( $access ) && ! empty( $access ) ) { - - $is_assoc = ( array_keys( $access ) !== range( 0, count( $access ) - 1 ) ); - - if( $is_assoc ) { - - $access[$this->user] = $this->access; - } else { - - $new_access = array(); - foreach( $access as $user ) { - - $new_access[$user] = Permission::LEVELS["delete"]; - } - $access[$this->user] = $this->access; - $access = $new_access; - } - } else { - - $access = array( - $this->user => $this->access - ); - } + exit( formatJSEND( "error", "Error fetching user information." ) ); + } + + $user = $sql->query( "SELECT * FROM access WHERE project = ? AND user = ?", array( $project["id"], $user_id ), array(), "fetch" ); + + if( ! empty( $user ) ) { - $access = json_encode( $access ); - $query = "UPDATE projects SET access=? WHERE path=? AND owner=?;"; - $bind_variables = array( $access, $this->path, $_SESSION["user"] ); - $return = $sql->query( $query, $bind_variables, 0, "rowCount" ); + $query = "UPDATE access SET level=? WHERE project=? AND user=?;"; + $bind_variables = array( $this->access, $project["id"], $user_id ); + $result = $sql->query( $query, $bind_variables, 0, "rowCount" ); if( $result > 0 ) { - - echo( formatJSEND( "success", "Successfully added {$this->user}." ) ); + + echo formatJSEND( "success", "Successfully updated {$this->user}." ); } else { echo formatJSEND( "error", "Error setting access for project." ); } } else { - echo formatJSEND( "error", "Error fetching projects." ); + $query = "INSERT INTO access ( project, user, level ) VALUES ( ?,?,? );"; + $bind_variables = array( $project["id"], $user_id, $this->access ); + $result = $sql->query( $query, $bind_variables, 0, "rowCount" ); + + if( $result > 0 ) { + + echo formatJSEND( "success", "Successfully added {$this->user}." ); + } else { + + echo formatJSEND( "error", "Error setting access for project." ); + } } } @@ -127,7 +124,7 @@ class Project extends Common { global $sql; $query = "SELECT owner FROM projects WHERE path=?"; $bind_variables = array( $path ); - $result = $sql->query( $query, $bind_variables, array() )[0]; + $result = $sql->query( $query, $bind_variables, array(), "fetch" ); $return = false; if( ! empty( $result ) ) { @@ -150,25 +147,12 @@ class Project extends Common { return( $return ); } - public function get_access( $path = null ) { + public function get_access( $project_id = null ) { - if( $path === null ) { - - $path = $this->path; - } global $sql; - $query = "SELECT access FROM projects WHERE path=?"; - $bind_variables = array( $path ); - $return = $sql->query( $query, $bind_variables, array() )[0]; - - if( ! empty( $return ) ) { - - $return = $return["access"]; - } else { - - $return = formatJSEND( "error", "Error fetching project info." ); - } - + $query = "SELECT * FROM access WHERE project=?"; + $bind_variables = array( $project_id ); + $return = $sql->query( $query, $bind_variables, array() ); return( $return ); } @@ -181,7 +165,7 @@ class Project extends Common { global $sql; $query = "SELECT owner FROM projects WHERE path=?"; $bind_variables = array( $path ); - $return = $sql->query( $query, $bind_variables, array() )[0]; + $return = $sql->query( $query, $bind_variables, array(), "fetch" ); if( ! empty( $return ) ) { @@ -200,10 +184,11 @@ class Project extends Common { $project = $this->path; } + global $sql; $query = " SELECT * FROM projects - WHERE path = ? + WHERE path = ? AND ( owner=? OR owner='nobody' @@ -212,7 +197,7 @@ class Project extends Common { $bind_variables = array( $project, $_SESSION["user"], $_SESSION["user_id"] ); //$query = "SELECT * FROM projects WHERE path=? AND ( owner=? OR owner='nobody' ) ORDER BY name;"; //$bind_variables = array( $project, $_SESSION["user"] ); - $return = $sql->query( $query, $bind_variables, array() )[0]; + $return = $sql->query( $query, $bind_variables, array(), "fetch" ); if( ! empty( $return ) ) { @@ -231,7 +216,7 @@ class Project extends Common { SELECT * FROM projects WHERE owner=? OR owner='nobody' - OR path IN ( SELECT path FROM access WHERE user = ? );"; + OR id IN ( SELECT project FROM access WHERE user = ? );"; $bind_variables = array( $_SESSION["user"], $_SESSION["user_id"] ); $return = $sql->query( $query, $bind_variables, array() ); @@ -246,42 +231,24 @@ class Project extends Common { public function remove_user() { global $sql; - $query = "SELECT access FROM projects WHERE path=? AND owner=?"; - $bind_variables = array( $this->path, $_SESSION["user"] ); - $result = $sql->query( $query, $bind_variables, array() )[0]; - - if( ! empty( $result ) ) { + + $user_id = get_user_id( $this->user ); + + if( $user_id === false ) { - $access = json_decode( $result["access"] ); + return formatJSEND( "error", "Error fetching user information." ); + } + + $query = "DELETE FROM access WHERE project=? AND user=?;"; + $bind_variables = array( $this->project_id, $user_id ); + $return = $sql->query( $query, $bind_variables, 0, "rowCount" ); + + if( $return > 0 ) { - if( is_array( $access ) ) { - - $key = array_search( $this->user, $access ); - - if ( $key !== false ) { - - unset( $access[$key] ); - } else { - - echo( formatJSEND( "error", "{$this->user} is not in the access list." ) ); - } - } - - $access = json_encode( $access ); - $query = "UPDATE projects SET access=? WHERE path=? AND owner=?;"; - $bind_variables = array( $access, $this->path, $_SESSION["user"] ); - $return = $sql->query( $query, $bind_variables, 0, "rowCount" ); - - if( $return > 0 ) { - - echo( formatJSEND( "success", "Successfully removed {$this->user}." ) ); - } else { - - echo formatJSEND( "error", "Error setting access for project." ); - } + echo( formatJSEND( "success", "Successfully removed {$this->user}." ) ); } else { - echo formatJSEND( "error", "Error fetching projects." ); + echo( formatJSEND( "error", "{$this->user} is not in the access list." ) ); } } diff --git a/components/project/controller.php b/components/project/controller.php index 21ea7cc..1ecaa81 100755 --- a/components/project/controller.php +++ b/components/project/controller.php @@ -34,13 +34,14 @@ if( $_GET['action'] == 'add_user' ) { if( ! isset( $_GET['access'] ) || in_array( $_GET['access'], $invalid_users ) || ! in_array( $_GET['access'], array_keys( Permissions::LEVELS ) ) ) { - echo formatJSEND( "error", "No access set." ); - return; + exit( formatJSEND( "error", "No access set." ) ); + } else { + + $Project->access = Permissions::LEVELS[$_GET['access']]; } if( isset( $_GET['username'] ) && ! in_array( $_GET['username'], $invalid_users ) ) { - $Project->access = $_GET['access']; $Project->user = $_GET['username']; } else { @@ -130,8 +131,7 @@ if( $_GET['action'] == 'delete' ) { if( $_GET['action'] == 'get_access' ) { - $Project->path = $_GET['project_path']; - $access = $Project->get_access( $_GET['project_path'] ); + $access = $Project->get_access( $_GET['project_id'] ); echo formatJSEND( "success", $access ); } @@ -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'] ) ); } @@ -212,8 +212,7 @@ if( $_GET['action'] == 'remove_user' ) { $Project->user = $_GET['username']; } else { - echo formatJSEND( "error", "No username set." ); - return; + exit( formatJSEND( "error", "No username set." ) ); } if( ! in_array( $_GET['project_path'], $invalid ) ) { @@ -221,8 +220,15 @@ if( $_GET['action'] == 'remove_user' ) { $Project->path = $_GET['project_path']; } else { - echo formatJSEND( "error", "No project path set." ); - return; + exit( formatJSEND( "error", "No project path set." ) ); + } + + if( ! in_array( $_GET['project_id'], $invalid ) ) { + + $Project->project_id = $_GET['project_id']; + } else { + + exit( formatJSEND( "error", "No project id set." ) ); } if( $Project->check_owner( $_GET["project_path"], true ) ) { @@ -230,7 +236,7 @@ if( $_GET['action'] == 'remove_user' ) { $Project->remove_user(); } else { - echo formatJSEND( "error", "You can not manage this project." ); + exit( formatJSEND( "error", "You can not manage this project." ) ); } } diff --git a/components/project/dialog.php b/components/project/dialog.php index 57b8df1..16d3af7 100755 --- a/components/project/dialog.php +++ b/components/project/dialog.php @@ -204,11 +204,12 @@ switch( $_GET['action'] ) { // Get projects data $path = $_GET['path']; $project = $Project->get_project( $path ); - $access = json_decode( $project["access"], true ); + $access = $Project->get_access( $project["id"] ); $users = get_users( "return", true ); ?> -
- + + + ">

No users have been given access.

@@ -234,30 +235,30 @@ switch( $_GET['action'] ) { $access_level ) { + foreach( $access as $row => $user_permissions ) { + + foreach( $users as $row => $current_user ) { + + if( $current_user["id"] == $user_permissions["user"] ) { + + $user = $current_user; + break; + } + } ?> rowCount(); break; + case( 'fetch' ): + + $return = $statement->fetch( \PDO::FETCH_ASSOC ); + break; + case( 'fetchAll' ): $return = $statement->fetchAll( \PDO::FETCH_ASSOC );
-

+

- +