Started new permissions module

This commit is contained in:
xevidos 2019-07-01 09:24:34 -04:00
parent 819602a87e
commit 6dd09ba1a6
8 changed files with 255 additions and 76 deletions

View File

@ -5,6 +5,9 @@
* [root]/license.txt for more. This information must remain intact. * [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);
$sql = null; $sql = null;
Common::startSession(); Common::startSession();
@ -93,6 +96,7 @@ class Common {
define( "LANGUAGE", "en" ); define( "LANGUAGE", "en" );
} }
require_once( COMPONENTS . "/permissions/class.permissions.php" );
require_once( COMPONENTS . "/update/class.update.php" ); require_once( COMPONENTS . "/update/class.update.php" );
require_once( COMPONENTS . "/sql/class.sql.php" ); require_once( COMPONENTS . "/sql/class.sql.php" );
global $sql; global $sql;
@ -564,47 +568,7 @@ class Common {
public static function checkPath( $path ) { public static function checkPath( $path ) {
global $sql; return Permissions::has_manager( $path );
//$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]",
$path,
array(
"more than",
0
)
),
array(
"limit",
1
)
)
);
if( ! empty( $result ) ) {
$result = $result[0];
try {
$users = json_decode( $result["access"] );
} catch( exception $e ) {
$users = array();
}
if( $result["owner"] == 'nobody' || $result["owner"] == $_SESSION["user"] || ( in_array( $_SESSION["user"], $users ) && ! empty( $users ) ) ) {
return( true );
}
}
return( false );
} }

View File

@ -450,7 +450,7 @@ class Filemanager extends Common {
public function delete( $keep_parent = false ) { public function delete( $keep_parent = false ) {
if( Common::checkPath( $path ) ) { if( ! Permissions::has_delete( $this->path ) ) {
$this->status = "error"; $this->status = "error";
$this->message = "No access."; $this->message = "No access.";
@ -530,7 +530,9 @@ class Filemanager extends Common {
if ( ! file_exists( $new_path ) ) { if ( ! file_exists( $new_path ) ) {
if ( rename( $this->path, $new_path ) ) { echo var_dump( Permissions::has_create( $this->path ) );
if ( Permissions::has_create( $this->path ) && rename( $this->path, $new_path ) ) {
//unlink($this->path); //unlink($this->path);
$this->status = "success"; $this->status = "success";
@ -560,7 +562,8 @@ class Filemanager extends Common {
$this->respond(); $this->respond();
return; return;
} }
if ( is_file( $this->path ) ) { echo var_dump( Permissions::has_write( $this->path ) );
if ( is_file( $this->path ) && Permissions::has_write( $this->path ) ) {
$serverMTime = filemtime( $this->path ); $serverMTime = filemtime( $this->path );
$fileContents = file_get_contents( $this->path ); $fileContents = file_get_contents( $this->path );

View File

@ -39,7 +39,8 @@ if (!isset($_SESSION['project'])) {
// Security Check // Security Check
////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////
if (!checkPath($_GET['path'])) { if ( ! Permissions::has_read( $_GET['path'] ) ) {
die('{"status":"error","message":"Invalid Path"}'); die('{"status":"error","message":"Invalid Path"}');
} }

View File

@ -0,0 +1,146 @@
<?php
/*
* Copyright (c) Codiad & Kent Safranski (codiad.com), and Isaac Brown (telaaedifex.com), distributed
* as-is and without warranty under the MIT License. See
* [root]/license.txt for more. This information must remain intact.
*/
class Permissions {
const LEVELS = array(
"admin" => 0,
"owner" => 1,
"manager" => 2,
"delete" => 3,
"create" => 4,
"write" => 5,
"read" => 6,
);
function __construct() {
}
public static function check_path( $level, $path ) {
$project_path = $_SESSION["project"];
$project_path = rtrim( $project_path, '/' ) . '/';
if( ! in_array( $level, array_keys( self::LEVELS ) ) ) {
exit( Common::formatJSEND( "error", "Access Level does not exist." ) );
}
if( strpos( $path, $project_path ) === 0 ) {
exit( Common::formatJSEND( "error", "Error with 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
)
)
);*/
$query = "SELECT * FROM projects WHERE path=? LIMIT 1;";
$bind_variables = array( $_SESSION["project"] );
$result = $sql->query( $query, $bind_variables, array() )[0];
if( ! empty( $result ) ) {
$result = $result[0];
try {
$users = json_decode( $result["access"], true );
} catch( exception $e ) {
$users = array();
}
if( $result["owner"] == 'nobody' ) {
$pass = true;
} elseif( $result["owner"] == $_SESSION["user"] ) {
$pass = true;
} elseif( in_array( $_SESSION["user"], array_keys( $users ) ) && ! empty( $users ) ) {
//Only allow the owner to delete the root dir / project
if( $path == $result["path"] && self::LEVELS[$level] == self::LEVELS["delete"] ) {
$level = "owner";
}
$is_assoc = ( array_keys( $users ) !== range( 0, count( $users ) - 1 ) );
if( $is_assoc ) {
$users_access = $users[$_SESSION["user"]];
} else {
$users_access = self::LEVELS["delete"];
}
echo var_dump( $path, $result, $users_access, $level, ( self::LEVELS[$level] >= $users_access ), self::LEVELS[$level] + " is more than or equal to {$users_access}" );
if( self::LEVELS[$level] >= $users_access ) {
$pass = true;
}
}
}
return( $pass );
}
public static function has_owner( $path ) {
return self::check_path( "owner", $path );
}
public static function has_manager( $path ) {
return self::check_path( "manager", $path );
}
public static function has_delete( $path ) {
return self::check_path( "delete", $path );
}
public static function has_create( $path ) {
return self::check_path( "create", $path );
}
public static function has_write( $path ) {
return self::check_path( "write", $path );
}
public static function has_read( $path ) {
return self::check_path( "read", $path );
}
}
?>

View File

@ -14,6 +14,7 @@ class Project extends Common {
// PROPERTIES // PROPERTIES
////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////
public $access = 100;
public $name = ''; public $name = '';
public $path = ''; public $path = '';
public $gitrepo = false; public $gitrepo = false;
@ -75,16 +76,27 @@ class Project extends Common {
$access = json_decode( $result["access"] ); $access = json_decode( $result["access"] );
if( is_array( $access ) ) { if( is_array( $access ) && ! empty( $access ) ) {
if( ! in_array( $this->user, $access ) ) { $is_assoc = ( array_keys( $access ) !== range( 0, count( $access ) - 1 ) );
array_push( $access, $this->user ); 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 { } else {
$access = array( $access = array(
$this->user $this->user => $this->access
); );
} }

View File

@ -32,8 +32,15 @@ if( $_GET['action'] == 'add_user' ) {
"undefined" "undefined"
); );
if( ! in_array( $_GET['username'], $invalid_users ) ) { 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;
}
if( isset( $_GET['username'] ) && ! in_array( $_GET['username'], $invalid_users ) ) {
$Project->access = $_GET['access'];
$Project->user = $_GET['username']; $Project->user = $_GET['username'];
} else { } else {
@ -110,7 +117,7 @@ if( $_GET['action'] == 'current' ) {
if( $_GET['action'] == 'delete' ) { if( $_GET['action'] == 'delete' ) {
if( checkPath( $_GET['project_path'] ) ) { if( isset( $_GET['project_path'] ) ) {
$Project->path = $_GET['project_path']; $Project->path = $_GET['project_path'];
$Project->Delete(); $Project->Delete();
@ -184,7 +191,7 @@ if( $_GET['action'] == 'get_owner' ) {
if( $_GET['action'] == 'open' ) { if( $_GET['action'] == 'open' ) {
if( ! checkPath( $_GET['path'] ) ) { if( isset( $_GET['path'] ) && ! Permissions::has_read( $_GET['path'] ) ) {
die( formatJSEND( "error", "No Access to path " . $_GET['path'] ) ); die( formatJSEND( "error", "No Access to path " . $_GET['path'] ) );
} }
@ -233,7 +240,7 @@ if( $_GET['action'] == 'remove_user' ) {
if( $_GET['action'] == 'rename' ) { if( $_GET['action'] == 'rename' ) {
if( ! checkPath( $_GET['project_path'] ) ) { if( ! isset( $_GET['project_path'] ) || ! Permissions::has_owner( $_GET['project_path'] ) ) {
die( formatJSEND( "error", "No Access" ) ); die( formatJSEND( "error", "No Access" ) );
} }

View File

@ -233,14 +233,41 @@ switch( $_GET['action'] ) {
?> ?>
<table id="access_list"> <table id="access_list">
<?php <?php
$is_assoc = ( array_keys( $access ) !== range( 0, count( $access ) - 1 ) );
if( ! $is_assoc ) {
$temp = array();
foreach( $access as $user ) { foreach( $access as $user ) {
$temp[$user] = "delete";
}
$access = $temp;
}
foreach( $access as $user => $access_level ) {
?> ?>
<tr> <tr>
<td> <td>
<p><?php echo htmlentities( $user );?></p> <p><?php echo htmlentities( $user );?></p>
</td> </td>
<td> <td>
<select onchange="codiad.project.change_access( event );">
<?php
foreach( Permissions::LEVELS as $level => $id ) {
if( $level == $access_level ) {
$selected = "selected='selected'";
} else {
$selected = "";
}
?><option value="<?php echo $level;?>" <?php echo $selected;?>><?php echo ucfirst( $level );?></option><?php
}
?>
</select>
<button class="btn-left" onclick="codiad.project.remove_user( '<?php echo htmlentities( $user );?>' );">Remove Access</button> <button class="btn-left" onclick="codiad.project.remove_user( '<?php echo htmlentities( $user );?>' );">Remove Access</button>
</td> </td>
</tr> </tr>

View File

@ -53,15 +53,15 @@
add_user: function() { add_user: function() {
var _this = this; let _this = this;
$( '#modal-content form' ).live( 'submit', function( e ) { $( '#modal-content form' ).live( 'submit', function( e ) {
e.preventDefault(); e.preventDefault();
username = $( '#modal-content form select[name="user_list"]' ).val(); let username = $( '#modal-content form select[name="user_list"]' ).val();
project_path = $( '#modal-content form input[name="project_path"]' ).val() let project_path = $( '#modal-content form input[name="project_path"]' ).val();
$.get( _this.controller + '?action=add_user&project_path=' + encodeURIComponent( project_path ) + '&username=' + encodeURIComponent( username ), function( data ) { $.get( _this.controller + '?action=add_user&project_path=' + encodeURIComponent( project_path ) + '&username=' + encodeURIComponent( username ) + '&access=delete', function( data ) {
response = codiad.jsend.parse( data ); response = codiad.jsend.parse( data );
console.log( response ); console.log( response );
@ -73,6 +73,25 @@
}); });
}, },
change_access: function( e ) {
let _this = codiad.project;
let username = $( '#modal-content form select[name="user_list"]' ).val();
let project_path = $( '#modal-content form input[name="project_path"]' ).val();
let access = $( e.target ).children( "option:selected" ).val();
console.log( access, username, project_path );
$.get( _this.controller + '?action=add_user&project_path=' + encodeURIComponent( project_path ) + '&username=' + encodeURIComponent( username ) + '&access=' + encodeURIComponent( access ), function( data ) {
let response = codiad.jsend.parse( data );
console.log( response );
if ( response != 'error' ) {
codiad.project.manage_access( project_path );
}
});
},
////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////
// Create Project // Create Project