* Added file selector functions

* Added initial archive management
* Added new Permissions system
* Added new file upload systems
* Recoded most of Filemanager componant
* Removed long IDs from database tables
* Updated commonly used settings to default
This commit is contained in:
xevidos 2020-03-30 17:57:38 +00:00
parent 9d718331e8
commit 6b9918acde
52 changed files with 6939 additions and 5873 deletions

View file

@ -1,25 +1,27 @@
# How to Contribute
Your contributions are welcome and we're very open about how contributions are made, however, to keep order to things please take the following into consideration:
Your contributions are welcome and we're very open about how contributions are made; however, to keep order to things please take the following into consideration:
* Check the issues to ensure that someone else isn't already working on the bug or feature
* Submit an issue for bugs and feature additions before you start with it
* Familiarize yourself with the documentation in the [Wiki](https://gitlab.com/xevidos/codiad/wikis/home)
There is an established format for `components` which utilizes one JS (`init.js`) and one CSS (`screen.css`) which is handled by the loader file. Any other resources used should be loaded or accessed from one of these.
**Merge Requests** All merge requests should be submitted for merging into the development branch. All tests and checks are run on that branch before merging into master to form a release.
**Don't Reinvent the Wheel!** There's an API and defined, easy-to-understand set of methods for a reason - use them.
There is an established format for `components` which utilizes one JS (`init.js`) and one CSS (`screen.css`) which is handled by the loader file. Any other resources used should be loaded or accessed from one of these. Plugins and Themes made for Codiad do not need to follow our formatting styles below, but any contributions to the core should.
**Don't Reinvent the Wheel!** There's an API and a defined, easy-to-understand set of methods for a reason - use them.
Stick to the conventions defined in other components as closely as possible.
* Utilize the same commenting structure
* Use underscores in namespaces instead of interCaps
* Use intend with a tab character in your code
* Use underscores in namespaces instead of camelCase
* Indent using tabs
* When working with the editor utilize the `active` object whenever possible instead of going direct to the `editor`
**Javascript Formatting**
In order to maintain a consistant code structure to the code across the application please follow the wordpress standard, or run any changes through [JSBeautifier] (http://jsbeautifier.org/) with the settings below.
In order to maintain a consistent code structure to the code across the application, please follow the WordPress standard, or run any changes through [JSBeautifier] (http://jsbeautifier.org/) with the settings below.
{
"brace_style": "collapse",
@ -50,4 +52,4 @@ If you have questions, please ask. Submit an issue or [contact us directly](mail
**PHP Formatting**
In order to maintain a consistant code structure we follow WordPress standards.
In order to maintain a consistent code structure we follow WordPress standards.

View file

@ -37,7 +37,9 @@ Current Tasks:
Task List:
* Add ability to create shortlinks with permissions for users to share files or projects.
* Add ability to login with LDAP
* Add bookmark files
* Add custom market
* \- Add in new admin interface ( Check admin-portal branch for progress )
- Group Management
@ -46,17 +48,24 @@ Task List:
- Project Management
- System Settings
- User Management
* Add Drag and Drop natively to filemanager
* Add folder / filestructure upload ability
* Add different code linters
* Add if file could not be saved 5 times close the open file
* Add multi level users. ( Projects for only certain groups, Permission levels )
* Add mobile compatibility
* Add permissions module ( more in depth permissions such as read/write, delete, etc )
* Add print code
* Add support for more archive types ( Add commands add more accepted PHP extension types )
* Add support for more database systems ( MSSQL, Oracle, SQLite, Filesystem storage, etc )
* Add in auto save timer that saves after the user stops typing instead of after every change
* Add terminal support ( optional per permission level )
* Clean up update script
* Create standards for php ( For example a lot of projects are using API like standards for their backends maybe create something like those? )
* Fix broken themes
* Re Add the custom language recognition system after recode
* Reformat install processes
* Remove all old and unneeded dependencies
* Seperate Upload filemanager instance from main filemanager instance
* Update all current components to use more current standards
- async await and .then in favor over callbacks in JS
- standards for php functions when created
Completed:

View file

@ -5,6 +5,9 @@
* [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;
Common::startSession();
@ -93,6 +96,18 @@ class Common {
define( "LANGUAGE", "en" );
}
if( ! defined( 'UPLOAD_CACHE' ) ) {
if( ! is_dir( sys_get_temp_dir() ) ) {
define( "UPLOAD_CACHE", DATA . "/uploads" );
} else {
define( "UPLOAD_CACHE", rtrim( sys_get_temp_dir(), "/" ) );
}
}
require_once( COMPONENTS . "/permissions/class.permissions.php" );
require_once( COMPONENTS . "/update/class.update.php" );
require_once( COMPONENTS . "/sql/class.sql.php" );
global $sql;
@ -103,96 +118,47 @@ 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 ) {
public static function get_user_id( $username ) {
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." ) );
$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 ) ) {
try {
$users = json_decode( $return["access"] );
} catch( exception $e ) {
$users = array();
$user_id = $return["id"];
}
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 );
return $user_id;
}
public static function get_users( $return = "return", $exclude_current = false ) {
global $sql;
$query = "SELECT username FROM users";
$bind = "";
$query = "SELECT * FROM users";
$bind_variables = array();
if( $exclude_current ) {
$query .= " WHERE username!=?";
$bind .= "s";
$query .= " WHERE username <> ?";
array_push( $bind_variables, $_SESSION["user"] );
}
$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 ) ) {
$result = $sql->query( $query, $bind_variables, array() );
switch( $return ) {
case( "json" ):
$return = json_encode( $user_list );
$return = json_encode( $result );
break;
case( "return" ):
$return = $user_list;
$return = $result;
break;
}
} else {
$return = formatJSEND( "error", "Error selecting user information." );
}
return( $return );
}
@ -204,10 +170,15 @@ class Common {
public static function is_admin() {
global $sql;
$query = "SELECT COUNT( * ) FROM users WHERE username=? AND access=?;";
$bind_variables = array( $_SESSION["user"], "admin" );
$admin = false;
if( isset( $_SESSION["user_id"] ) ) {
$query = "SELECT COUNT( * ) FROM users WHERE id=? AND access=?;";
$bind_variables = array( $_SESSION["user_id"], Permissions::SYSTEM_LEVELS["admin"] );
$return = $sql->query( $query, $bind_variables, -1, 'fetchColumn' );
$admin = ( $return > 0 );
}
return $admin;
}
@ -302,8 +273,18 @@ class Common {
Common::construct();
//Set a Session Name
try {
session_name( md5( BASE_PATH ) );
session_save_path( SESSIONS_PATH );
} catch( exception $e ) {
}
if( ! is_dir( SESSIONS_PATH ) ) {
mkdir( SESSIONS_PATH );
}
session_start();
if( ! defined( 'SESSION_ID' ) ) {
@ -353,32 +334,7 @@ class Common {
public static function startSession() {
Common::construct();
//Set a Session Name
session_name( md5( BASE_PATH ) );
session_save_path( SESSIONS_PATH );
session_start();
if( ! defined( 'SESSION_ID' ) ) {
define( "SESSION_ID", session_id() );
}
//Check for external authentification
if( defined( 'AUTH_PATH' ) ) {
require_once( AUTH_PATH );
}
global $lang;
if ( isset( $_SESSION['lang'] ) ) {
include BASE_PATH . "/languages/{$_SESSION['lang']}.php";
} else {
include BASE_PATH . "/languages/" . LANGUAGE . ".php";
}
Common::start_session();
}
//////////////////////////////////////////////////////////////////
@ -452,11 +408,11 @@ class Common {
$pass = false;
if( isset( $_SESSION["token"] ) && isset( $_SESSION["user"] ) ) {
if( isset( $_SESSION["token"] ) && isset( $_SESSION["user_id"] ) ) {
global $sql;
$query = "SELECT COUNT( * ) FROM users WHERE username=? AND token=?;";
$bind_variables = array( $_SESSION["user"], sha1( $_SESSION["token"] ) );
$query = "SELECT COUNT( * ) FROM users WHERE id=? AND token=?;";
$bind_variables = array( $_SESSION["user_id"], sha1( $_SESSION["token"] ) );
$return = $sql->query( $query, $bind_variables, formatJSEND( "error", "Error checking access." ), "fetchColumn" );
if( $return > 0 ) {
@ -520,33 +476,43 @@ class Common {
// Format JSEND Response
//////////////////////////////////////////////////////////////////
public static function formatJSEND( $status, $data = false ) {
public static function formatJSEND( $status, $data = false, $debug = false ) {
/// Debug /////////////////////////////////////////////////
$debug = "";
$jsend = array(
"status" => null,
"data" => null,
"debug" => null,
"message" => null,
);
if( count( Common::$debugMessageStack ) > 0 ) {
$debug .= ',"debug":';
$debug .= json_encode( Common::$debugMessageStack );
$jsend["debug"] = json_encode( Common::$debugMessageStack );
}
if( $debug ) {
$jsend["debug"] = $debug;
}
if( $status == "success" ) {
// Success ///////////////////////////////////////////////
$jsend["status"] = "success";
if( $data ) {
$jsend = '{"status":"success","data":' . json_encode( $data ) . $debug . '}';
} else {
$jsend = '{"status":"success","data":null' . $debug . '}';
$jsend["data"] = $data;
}
} else {
// Error /////////////////////////////////////////////////
$jsend = '{"status":"' . $status . '","message":"' . $data . '"' . $debug . '}';
$jsend["status"] = "error";
$jsend["message"] = $data;
}
// Return ////////////////////////////////////////////////
return $jsend;
return json_encode( $jsend );
}
//////////////////////////////////////////////////////////////////
@ -564,47 +530,7 @@ class Common {
public static function checkPath( $path ) {
global $sql;
//$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 );
return Permissions::has_manager( $path );
}
@ -651,19 +577,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 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 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 get_users( $return = "return", $exclude_current = false ) { return Common::get_users( $return, $exclude_current ); }
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 ); }
function get_version() { return Common::get_version(); }
?>

View file

@ -14,7 +14,6 @@ class Active extends Common {
// PROPERTIES
//////////////////////////////////////////////////////////////////
public $username = "";
public $path = "";
public $new_path = "";
@ -31,6 +30,17 @@ class Active extends Common {
public function __construct() {
}
public static function remove( $path ) {
global $sql;
$query = array(
"*" => "DELETE FROM active WHERE path=? AND user=?;",
"pgsql" => 'DELETE FROM active WHERE path=? AND "user"=?;',
);
$bind_variables = array( $path, $_SESSION["user_id"] );
$return = $sql->query( $query, $bind_variables, 0, "rowCount" );
}
//////////////////////////////////////////////////////////////////
// List User's Active Files
//////////////////////////////////////////////////////////////////
@ -38,14 +48,17 @@ class Active extends Common {
public function ListActive() {
global $sql;
$query = "SELECT path,position,focused FROM active WHERE username=?";
$bind_variables = array( $this->username );
$query = array(
"*" => "SELECT path, position, focused FROM active WHERE user=?",
"pgsql" => 'SELECT path, position, focused FROM active WHERE "user"=?',
);
$bind_variables = array( $_SESSION["user_id"] );
$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 +70,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 ) );
}
//////////////////////////////////////////////////////////////////
@ -80,7 +87,10 @@ class Active extends Common {
public function Check() {
global $sql;
$query = "SELECT username FROM active WHERE path=?";
$query = array(
"*" => "SELECT user FROM active WHERE path=?",
"pgsql" => 'SELECT "user" FROM active WHERE path=?',
);
$bind_variables = array( $this->path );
$result = $sql->query( $query, $bind_variables, array() );
$tainted = false;
@ -90,10 +100,11 @@ class Active extends Common {
foreach( $result as $id => $data ) {
array_push( $users, $data["username"] );
if( $data["username"] == $this->username ) {
array_push( $users, $data["user"] );
if( $data["user"] == $_SESSION ) {
$user = true;
break;
}
}
@ -113,15 +124,39 @@ class Active extends Common {
public function Add() {
global $sql;
$query = "INSERT INTO active( username, path, focused ) VALUES ( ?, ?, ? );";
$bind_variables = array( $this->username, $this->path, false );
$return = $sql->query( $query, $bind_variables, 0, "rowCount" );
$query = array(
"*" => "SELECT focused FROM active WHERE path=? AND user=? LIMIT 1;",
"pgsql" => 'SELECT focused FROM active WHERE path=? AND "user"=? LIMIT 1;',
);
$bind_variables = array( $this->path, $_SESSION["user_id"] );
$result = $sql->query( $query, $bind_variables, array() );
if( $return > 0 ) {
if( count( $result ) == 0 ) {
$query = array(
"*" => "UPDATE active SET focused=false WHERE user=? AND path=?;",
"pgsql" => 'UPDATE active SET focused=false WHERE "user"=? AND path=?;',
);
$bind_variables = array( $_SESSION["user_id"], $this->path );
$result = $sql->query( $query, $bind_variables, 0, "rowCount" );
if( $result == 0 ) {
global $sql;
$query = array(
"*" => "INSERT INTO active( user, path, focused ) VALUES ( ?, ?, ? );",
"pgsql" => 'INSERT INTO active( "user", path, focused ) VALUES ( ?, ?, ? );',
);
$bind_variables = array( $_SESSION["user_id"], $this->path, false );
$result = $sql->query( $query, $bind_variables, 0, "rowCount" );
if( $result > 0 ) {
echo formatJSEND( "success" );
}
}
}
}
//////////////////////////////////////////////////////////////////
// Rename File
@ -140,23 +175,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
//////////////////////////////////////////////////////////////////
@ -164,8 +182,11 @@ class Active extends Common {
public function RemoveAll() {
global $sql;
$query = "DELETE FROM active WHERE username=?;";
$bind_variables = array( $this->username );
$query = array(
"*" => "DELETE FROM active WHERE user=?;",
"pgsql" => 'DELETE FROM active WHERE "user"=?;',
);
$bind_variables = array( $_SESSION["user_id"] );
$return = $sql->query( $query, $bind_variables, 0, "rowCount" );
if( $return > 0 ) {
@ -182,8 +203,11 @@ class Active extends Common {
public function MarkFileAsFocused() {
global $sql;
$query = "UPDATE active SET focused=? WHERE username=?;UPDATE active SET focused=? WHERE path=? AND username=?;";
$bind_variables = array( false, $this->username, true, $this->path, $this->username );
$query = array(
"*" => "UPDATE active SET focused=? WHERE path=? AND user=?;",
"pgsql" => 'UPDATE active SET focused=? WHERE path=? AND "user"=?;',
);
$bind_variables = array( true, $this->path, $_SESSION["user_id"] );
$return = $sql->query( $query, $bind_variables, 0, "rowCount" );
if( $return > 0 ) {
@ -196,19 +220,19 @@ class Active extends Common {
global $sql;
$positions = json_decode( $positions, true );
$query = "";
$query = array(
"mysql" => "UPDATE active SET position=? WHERE path=? AND user=?;",
"pgsql" => 'UPDATE active SET position=? WHERE path=? AND "user"=?;',
);
$bind_variables = array();
if( json_last_error() == JSON_ERROR_NONE ) {
foreach( $positions as $path => $cursor ) {
$query .= "UPDATE active SET position=? WHERE path=? AND username=?;";
array_push( $bind_variables, json_encode( $cursor ), $path, $this->username );
$return = $sql->query( $query, array( json_encode( $cursor ), $path, $_SESSION["user_id"] ), 0, "rowCount" );
}
$return = $sql->query( $query, $bind_variables, 0, "rowCount" );
if( $return > 0 ) {
exit( formatJSEND( "success" ) );

View file

@ -22,6 +22,7 @@
//////////////////////////////////////////////////////////////////
if( $_GET['action'] == 'list' ) {
$Active->username = $_SESSION['user'];
$Active->ListActive();
}
@ -31,6 +32,7 @@ if ($_GET['action']=='list') {
//////////////////////////////////////////////////////////////////
if ( $_GET['action'] == 'add' ) {
$Active->username = $_SESSION['user'];
$Active->path = $_GET['path'];
$Active->Add();
@ -41,6 +43,7 @@ if ($_GET['action']=='add') {
//////////////////////////////////////////////////////////////////
if ( $_GET['action'] == 'rename' ) {
$Active->username = $_SESSION['user'];
$Active->path = $_GET['old_path'];
$Active->new_path = $_GET['new_path'];
@ -52,6 +55,7 @@ if ($_GET['action']=='rename') {
//////////////////////////////////////////////////////////////////
if ( $_GET['action'] == 'check' ) {
$Active->username = $_SESSION['user'];
$Active->path = $_GET['path'];
$Active->Check();
@ -62,9 +66,10 @@ if ($_GET['action']=='check') {
//////////////////////////////////////////////////////////////////
if ( $_GET['action'] == 'remove' ) {
$Active->username = $_SESSION['user'];
$Active->path = $_GET['path'];
$Active->Remove();
$Active->remove( $Active->path );
}
//////////////////////////////////////////////////////////////////
@ -72,6 +77,7 @@ if ($_GET['action']=='remove') {
//////////////////////////////////////////////////////////////////
if( $_GET['action'] == 'removeall' ) {
$Active->username = $_SESSION['user'];
$Active->RemoveAll();
}
@ -81,6 +87,7 @@ if ($_GET['action']=='removeall') {
//////////////////////////////////////////////////////////////////
if( $_GET['action'] == 'focused' ) {
$Active->username = $_SESSION['user'];
$Active->path = $_GET['path'];
$Active->MarkFileAsFocused();

View file

@ -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 );
}
@ -113,8 +113,7 @@
};
// Assuming the mode file has no dependencies
$.loadScript( 'components/editor/ace-editor/mode-' + mode.name + '.js',
fn );
$.loadScript( 'components/editor/ace-editor/mode-' + mode.name + '.js', fn );
},
init: function() {
@ -275,6 +274,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 ) {
@ -361,6 +361,9 @@
session.listThumb = listThumb;
$( '#list-active-files' ).append( listThumb );
/* If the tab list would overflow with the new tab. Move the
* first tab to dropdown, then add a new tab. */
if( this.isTabListOverflowed( true ) ) {
@ -374,7 +377,10 @@
this.updateTabDropdownVisibility();
$.get( this.controller + '?action=add&path=' + encodeURIComponent( path ) );
$.get( this.controller + '?action=add&path=' + encodeURIComponent( path ), function( data ) {
//console.log( data );
});
if( focus ) {
this.focus( path );
@ -440,7 +446,7 @@
var session = this.sessions[path];
if( $( '#dropdown-list-active-files' ).has( session.tabThumb ).length > 0 ) {
if( session && session.tabThumb && $( '#dropdown-list-active-files' ).has( session.tabThumb ).length > 0 ) {
if( moveToTabList ) {
/* Get the menu item as a tab, and put the last tab in
* dropdown. */
@ -494,11 +500,11 @@
.getSession();
var content = session.getValue();
var path = session.path;
var handleSuccess = function( mtime ) {
var handleSuccess = function( result ) {
var session = codiad.active.sessions[path];
if( typeof session != 'undefined' ) {
session.untainted = newContent;
session.serverMTime = mtime;
session.serverMTime = result.data.mtime;
if( session.listThumb ) session.listThumb.removeClass( 'changed' );
if( session.tabThumb ) session.tabThumb.removeClass( 'changed' );
}
@ -516,20 +522,30 @@
original: session.untainted,
changed: newContent
}, function( success, patch ) {
console.log( "diff test", success, patch );
if( success ) {
codiad.filemanager.savePatch( path, patch, session.serverMTime, {
success: handleSuccess
}, alerts );
if( patch.length > 0 ) {
codiad.filemanager.save_file( path, {
patch: patch,
mtime: session.serverMTime
}, alerts )
.then( handleSuccess );
}
} else {
codiad.filemanager.saveFile( path, newContent, {
success: handleSuccess
}, alerts );
console.log( "calling save while failed diff", path, newContent, alerts );
codiad.filemanager.save_file( path, {content: newContent}, alerts )
.then( handleSuccess );
}
}, this );
} else {
codiad.filemanager.saveFile( path, newContent, {
success: handleSuccess
}, alert );
console.log( "calling save without mtime and untainted", path, newContent, alerts );
codiad.filemanager.save_file( path, {content: newContent}, alerts )
.then( handleSuccess );
}
},
@ -551,9 +567,11 @@
//////////////////////////////////////////////////////////////////
remove: function( path ) {
console.log( "remove file", this.isOpen( path ) );
if( !this.isOpen( path ) ) return;
var session = this.sessions[path];
var closeFile = true;
let session = this.sessions[path];
let closeFile = true;
if( session.listThumb.hasClass( 'changed' ) ) {
codiad.modal.load( 450, 'components/active/dialog.php?action=confirm&path=' + encodeURIComponent( path ) );
closeFile = false;
@ -745,14 +763,18 @@
//////////////////////////////////////////////////////////////////
getSelectedText: function() {
var path = this.getPath();
var session = this.sessions[path];
let path = this.getPath();
let session = this.sessions[path];
if( path && this.isOpen( path ) ) {
return session.getTextRange(
codiad.editor.getActive()
.getSelectionRange() );
console.log( "Session:", session );
console.log( "selection: ", codiad.editor.getActive().getSelectionRange() )
console.log( "text: ", session.getTextRange( codiad.editor.getActive().getSelectionRange() ) )
return session.getTextRange( codiad.editor.getActive().getSelectionRange() );
} else {
codiad.message.error( i18n( 'No Open Files or Selected Text' ) );
}
},
@ -1013,6 +1035,8 @@
uploadPositions: function() {
if( Object.keys( codiad.active.positions ).length > 0 ) {
$.ajax( {
type: 'POST',
url: codiad.active.controller + '?action=save_positions',
@ -1021,6 +1045,7 @@
},
success: function( data ) {},
});
}
},
savePosition: function() {

View file

@ -228,7 +228,11 @@
_this.content = content;
codiad.active.save;
codiad.filemanager.saveFile( path, content, localStorage.removeItem( path ), false );
codiad.filemanager.save_file( path, {content: content}, false )
.then( function( i ) {
localStorage.removeItem( path );
});
let session = codiad.active.sessions[path];
if( typeof session != 'undefined' ) {

View file

@ -19,6 +19,17 @@ checkSession();
<?php
switch( $_GET['action'] ) {
case 'line':
?>
<label><?php i18n("Goto Line:"); ?></label>
<input name="goto_line" type="number" autofocus="autofocus" autocomplete="off">
<button class="btn-left" onclick="codiad.editor.goto_line();return false;"><?php i18n("Goto"); ?></button>
<button class="btn-right" onclick="codiad.modal.unload(); return false;"><?php i18n("Cancel"); ?></button>
<?php
break;
break;
case 'search':
//////////////////////////////////////////////////////////////////
@ -75,28 +86,3 @@ checkSession();
}
?>
</form>
<script>
$( function() {
<?php
if( $_GET['action'] == 'search' ) {
?>
if( codiad.editor.multi_line ) {
$('textarea[name="find"]').val( codiad.active.getSelectedText() );
$('textarea[name="find"]').focus();
} else {
$('input[name="find"]').val( codiad.active.getSelectedText() );
$('input[name="find"]').focus();
}
<?php
} elseif( $_GET['action'] == 'sort' ) {
?>
$('textarea[name="sort"]').val( codiad.active.getSelectedText() );
$('textarea[name="sort"]').focus();
<?php
}
?>
});
</script>

View file

@ -297,7 +297,7 @@
let path = codiad.active.getPath();
$( e.target ).attr( 'data-path', path );
codiad.filemanager.contextMenuShow( e, path, 'editor', 'editor' );
codiad.filemanager.display_context_menu( e, path, 'editor', 'editor' );
$( this ).addClass( 'context-menu-active' );
}
});
@ -395,6 +395,11 @@
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 {
@ -1287,6 +1296,11 @@
' &middot; ' + i18n( 'Col' ) + ': ' +
i.getCursorPosition().column
);
amplify.publish( 'editor.changeCursor', {
i: i,
row: i.getCursorPosition().row,
column: i.getCursorPosition().column,
});
//Register the changecursor function so updates continue
i.selection.on( "changeCursor", function( e ) {
@ -1298,6 +1312,12 @@
' &middot; ' + i18n( 'Col' ) + ': ' +
i.getCursorPosition().column
);
amplify.publish( 'editor.changeCursor', {
i: i,
row: i.getCursorPosition().row,
column: i.getCursorPosition().column,
});
});
},
@ -1312,54 +1332,32 @@
bindKeys: function( i ) {
//Add key bindings to editor so we overwrite any already Setup
//by the ace editor.
var _this = this;
// Find
i.commands.addCommand( {
name: 'Find',
bindKey: {
win: 'Ctrl-F',
mac: 'Command-F'
},
exec: function( e ) {
_this.openSearch( 'find' );
}
});
codiad.keybindings.bindings.forEach( function( m, j, a ) {
// Find + Replace
i.commands.addCommand( {
name: 'Replace',
bindKey: {
win: 'Ctrl-R',
mac: 'Command-R'
},
exec: function( e ) {
_this.openSearch( 'replace' );
}
i.commands.addCommand( m );
});
i.commands.addCommand( {
name: 'Move Up',
bindKey: {
win: 'Ctrl-up',
mac: 'Command-up'
},
exec: function( e ) {
codiad.active.move( 'up' );
}
});
i.commands.addCommand( {
name: 'Move Down',
bindKey: {
win: 'Ctrl-down',
mac: 'Command-up'
open_goto: function() {
if( this.getActive() ) {
codiad.modal.load( 400, 'components/editor/dialog.php?action=line' );
codiad.modal.hideOverlay();
} else {
codiad.message.error( 'No Open Files' );
}
},
exec: function( e ) {
codiad.active.move( 'down' );
}
});
goto_line: function() {
let line = $( '#modal input[name="goto_line"]' ).val();
this.gotoLine( line );
codiad.modal.unload();
},
//////////////////////////////////////////////////////////////////
@ -1372,13 +1370,34 @@
//////////////////////////////////////////////////////////////////
openSearch: function( type ) {
if( this.getActive() ) {
codiad.modal.load( 400,
'components/editor/dialog.php?action=search&type=' +
type );
let selected = codiad.active.getSelectedText();
codiad.modal.load(
400,
'components/editor/dialog.php?action=search&type=' + type,
{},
)
.then( function( c ) {
let input = c.find( 'input:first' );
let textarea = c.find( 'textarea:first' );
if( input.css( 'display' ) !== 'none' ) {
input.val( selected )
input.focus();
} else if( textarea.css( 'display' ) !== 'none' ) {
textarea.val( selected )
textarea.focus();
}
console.log( input, textarea );
codiad.modal.hideOverlay();
} else {
codiad.message.error( 'No Open Files' );
}
);
}
},
@ -1408,6 +1427,9 @@
var replace = $( '#modal input[name="replace"]' )
.val();
}
console.log( action, i, find, replace );
switch ( action ) {
case 'find':
@ -1556,9 +1578,23 @@
openSort: function() {
if( this.getActive() && codiad.active.getSelectedText() != "" ) {
let selected = codiad.active.getSelectedText();
codiad.modal.load( 400, 'components/editor/dialog.php?action=sort' );
if( this.getActive() && selected != "" ) {
codiad.modal.load(
400,
'components/editor/dialog.php?action=sort',
{}
)
.then( function( c ) {
let textarea = c.find( 'textarea:first' );
textarea.val( selected )
textarea.focus();
codiad.modal.hideOverlay();
});
codiad.modal.hideOverlay();
} else {

View file

@ -0,0 +1,308 @@
<?php
class Archive {
const COMMANDS = array(
"zip" => array(
"compress" => array(
"windows" => "",
"linux" => "zip -r9 %output% %input%",
),
"decompress" => array(
"windows" => "",
"linux" => "unzip %input%",
),
),
);
const EXTENSIONS = array(
"zip" => "zip",
);
const INVALID_FILES = array(
".",
"..",
".DS_Store"
);
const MIME_TYPE_EXTENSIONS = array(
"application/zip" => "zip",
);
const SUPPORTED_TYPES = array(
//"gz",
//"rar",
//"tar",
//"tar.gz",
"zip",
);
public static $instance = null;
public $manager = null;
function __construct() {
}
public static function get_instance() {
if ( null == self::$instance ) {
self::$instance = new self;
}
return self::$instance;
}
public static function get_system() {
$system = "unknown";
if( strtoupper( substr( PHP_OS, 0, 3 ) ) === 'WIN' ) {
$system = "windows";
} else {
$system = "linux";
}
return $system;
}
public static function compress( $path, $output = "default", $type = "default" ) {
$response = array();
if( $type == "default" ) {
$type = self:: get_supported_type();
}
if( $output == "default" ) {
$output = dirname( $path ) . "/" . basename( $path ) . ".$type";
$path_parts = pathinfo( $output );
$existing = $output;
$i = 1;
do {
if( is_dir( $existing ) ) {
$existing = rtrim( $output, "/" ) . " $i/";
} elseif( is_file( $existing ) ) {
if( isset( $path_parts["extension"] ) ) {
$existing = str_replace( ".{$path_parts["extension"]}", " {$i}.{$path_parts["extension"]}", $output );
} else {
$existing = $output . " $i";
}
}
$i++;
} while( is_file( $existing ) || is_dir( $existing ) );
$output = $existing;
}
$supported = self::supports( $type );
$archive = self::get_instance();
if( $supported["status"] === "success" ) {
if( extension_loaded( self::EXTENSIONS["{$type}"] ) ) {
$response = call_user_func( array( $archive, "{$type}_c" ), $path, $output );
} else {
//$response = $archive->execute( $type, "compress", $path, dirname( $path ) );
}
} else {
$response = $supported;
}
return $response;
}
public static function decompress( $file, $output = "default" ) {
$response = array();
$path_info = pathinfo( $file );
$type = isset( $path_info["extension"] ) ? $path_info["extension"] : null;
$supported = self::supports( $type );
$archive = self::get_instance();
if( $output == "default" ) {
$output = $path_info["dirname"] . "/" . $path_info["filename"];
}
if( $supported["status"] === "success" ) {
if( extension_loaded( self::EXTENSIONS["{$type}"] ) ) {
$response = call_user_func( array( $archive, "{$type}_d" ), $file, $output );
} else {
$response = $archive->execute( $type, "decompress" );
}
if( $response === true ) {
$response = array(
"status" => "success",
"message" => null,
);
}
} else {
$response = $supported;
}
return $response;
}
public static function get_supported_type() {
//zip is usually the most used format supported by the most OS's,
//we check that first then check the rest of the types.
$supported_type = null;
$types = self::SUPPORTED_TYPES;
$zip_id = array_search( "zip", $types );
unset( $types[$zip_id] );
array_unshift( $types, "zip" );
foreach( $types as $id => $type ) {
if( self::supports( $type ) ) {
$supported_type = $type;
break;
}
}
return $supported_type;
}
public static function supports( $type ) {
$response = array();
$type = strtolower( $type );
if( in_array( $type, self::SUPPORTED_TYPES ) ) {
$system = self::get_system();
$supported = false;
$extension = self::EXTENSIONS["{$type}"];
if( extension_loaded( $extension ) ) {
$type_supported = true;
} elseif( isset( self::COMMANDS["{$type}"] ) && isset( self::COMMANDS["{$type}"]["compress"][$system] ) ) {
$type_supported = true;
}
if( $type_supported ) {
$response["status"] = "success";
$response["message"] = "Type is supported";
} else {
$response["status"] = "error";
$response["message"] = "The extension or program required to use this type of file does not seem to be installed.";
}
} else {
$response["status"] = "error";
$response["message"] = "The filetype supplied is not currently supported by Codiad's archive management system.";
}
return $response;
}
function zip_c( $path, $output, &$archive = null ) {
if( $archive == null ) {
$path = rtrim( $path, '/' );
//$output = rtrim( $output, '/' ) . '/';
$archive = new ZipArchive();
if( file_exists( $output ) ) {
$result = $archive->open( $output, ZIPARCHIVE::OVERWRITE );
} else {
$result = $archive->open( $output, ZIPARCHIVE::CREATE );
}
if( $result !== true ) {
return false;
}
if( is_file( $path ) ) {
$archive->addFile( $path, basename( $path ) );
$archive->close();
return true;
}
}
$i = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $path ) );
foreach( $i as $file ) {
$file_name = $file->getBasename();
$file_path = $file->getPathname();
$relative_path = str_replace( $path, "", $file_path );
$relative_path = ltrim( $relative_path, '/' );
if( in_array( $file_name, self::INVALID_FILES ) ) {
continue;
}
if( is_file( $file_path ) ) {
$archive->addFile( $file_path, $relative_path );
} else {
$archive->addEmptyDir( $relative_path );
$this->zip_c( $file_path, $output, $archive );
}
}
$archive->close();
return true;
}
function zip_d( $path, $output ) {
if( ! is_dir( $output ) ) {
mkdir( $output );
}
$status = false;
$output = rtrim( $output, '/' ) . '/';
$archive = new ZipArchive();
$open = $archive->open( $path );
if ( $open === true ) {
$archive->extractTo( $output );
$archive->close();
$status = true;
}
return $status;
}
}
?>

View file

@ -1,55 +0,0 @@
<?php
/**
* @author umbalaconmeogia at NOSPAM dot gmail dot com
* @link http://www.php.net/manual/de/class.ziparchive.php#110719
*/
class DirZip
{
/**
* Add files and sub-directories in a folder to zip file.
* @param string $folder
* @param ZipArchive $zipFile
* @param int $exclusiveLength Number of text to be exclusived from the file path.
*/
private static function folderToZip($folder, &$zipFile, $exclusiveLength)
{
$handle = opendir($folder);
while ($f = readdir($handle)) {
if ($f != '.' && $f != '..') {
$filePath = "$folder/$f";
// Remove prefix from file path before add to zip.
$localPath = substr($filePath, $exclusiveLength);
if (is_file($filePath)) {
$zipFile->addFile($filePath, $localPath);
} elseif (is_dir($filePath)) {
// Add sub-directory.
$zipFile->addEmptyDir($localPath);
self::folderToZip($filePath, $zipFile, $exclusiveLength);
}
}
}
closedir($handle);
}
/**
* Zip a folder (include itself).
* Usage:
* DirZip::zipDir('/path/to/sourceDir', '/path/to/out.zip');
*
* @param string $sourcePath Path of directory to be zip.
* @param string $outZipPath Path of output zip file.
*/
public static function zipDir($sourcePath, $outZipPath)
{
$pathInfo = pathInfo($sourcePath);
$parentPath = $pathInfo['dirname'];
$dirName = $pathInfo['basename'];
$z = new ZipArchive();
$z->open($outZipPath, ZIPARCHIVE::CREATE);
$z->addEmptyDir($dirName);
self::folderToZip($sourcePath, $z, strlen("$parentPath/"));
$z->close();
}
}

File diff suppressed because it is too large Load diff

View file

@ -3,13 +3,13 @@
"title": "New File",
"icon": "icon-doc-text",
"applies-to": "directory-only",
"onclick": "codiad.filemanager.createNode($('#context-menu').attr('data-path'),'file');"
"onclick": "codiad.filemanager.create_node($('#context-menu').attr('data-path'),'file');"
},
{
"title": "New Folder",
"icon": "icon-folder",
"applies-to": "directory-only",
"onclick": "codiad.filemanager.createNode($('#context-menu').attr('data-path'),'directory');"
"onclick": "codiad.filemanager.create_node($('#context-menu').attr('data-path'),'directory');"
},
{
"title": "Break",
@ -39,7 +39,7 @@
"title": "Preview",
"icon": "icon-eye",
"applies-to": "both no-external",
"onclick": "codiad.filemanager.openInBrowser($('#context-menu').attr('data-path'));"
"onclick": "codiad.filemanager.preview($('#context-menu').attr('data-path'));"
},
{
"title": "Break",
@ -47,6 +47,18 @@
"applies-to": "file-only no-external",
"onclick": null
},
{
"title": "Archive",
"icon": "icon-archive",
"applies-to": "directory-only non-root",
"onclick": "codiad.filemanager.archive( $('#context-menu').attr('data-path') );"
},
{
"title": "Unarchive",
"icon": "icon-archive",
"applies-to": "file-only non-root",
"onclick": "codiad.filemanager.unarchive( $('#context-menu').attr('data-path') );"
},
{
"title": "Break",
"icon": null,
@ -63,7 +75,7 @@
"title": "Paste",
"icon": "icon-docs",
"applies-to": "directory-only",
"onclick": "codiad.filemanager.pasteNode($('#context-menu').attr('data-path'));"
"onclick": "codiad.filemanager.paste_node($('#context-menu').attr('data-path'));"
},
{
"title": "Break",
@ -75,7 +87,7 @@
"title": "Rename",
"icon": "icon-pencil",
"applies-to": "non-root",
"onclick": "codiad.filemanager.renameNode($('#context-menu').attr('data-path'));"
"onclick": "codiad.filemanager.open_rename($('#context-menu').attr('data-path'));"
},
{
"title": "Rename Project",
@ -105,7 +117,7 @@
"title": "Delete Contents",
"icon": "icon-cancel-circled",
"applies-to": "directory-only",
"onclick": "codiad.filemanager.deleteInnerNode($('#context-menu').attr('data-path'));"
"onclick": "codiad.filemanager.delete_children_nodes($('#context-menu').attr('data-path'));"
},
{
"title": "Break",

View file

@ -19,10 +19,20 @@
// Get Action
//////////////////////////////////////////////////////////////////
$response = array(
"status" => "none",
);
if( ! empty($_GET['action'] ) ) {
$action = $_GET['action'];
} else {
exit('{"status":"error","data":{"error":"No Action Specified"}}');
$response["status"] = "error";
$response["data"] = array(
"error" => "No action specified"
);
exit( json_encode( $response ) );
}
//////////////////////////////////////////////////////////////////
@ -30,66 +40,315 @@ if (!empty($_GET['action'])) {
//////////////////////////////////////////////////////////////////
if( ! isset( $_SESSION['project'] ) ) {
$_GET['action'] = 'get_current';
$_GET['no_return'] = 'true';
require_once('../project/controller.php');
}
if( isset( $_GET["path"] ) || isset( $_POST["path"] ) ) {
$path = isset( $_GET["path"] ) ? $_GET["path"] : $_POST["path"];
} else {
$response["status"] = "error";
$response["message"] = "Missing path.";
$response["GET"] = $_GET;
$response["POST"] = $_POST;
exit( json_encode( $response ) );
}
//////////////////////////////////////////////////////////////////
// Security Check
//////////////////////////////////////////////////////////////////
if (!checkPath($_GET['path'])) {
die('{"status":"error","message":"Invalid Path"}');
$access = Permissions::get_access( $path );
if ( ! Permissions::check_access( "read", $access ) ) {
$response["status"] = "error";
$response["message"] = "Invalid access to path";
$response["path"] = $path;
exit( json_encode( $response ) );
}
//////////////////////////////////////////////////////////////////
// Define Root
//////////////////////////////////////////////////////////////////
if( isset( $_GET["destination"] ) || isset( $_POST["destination"] ) ) {
$_GET['root'] = WORKSPACE;
$destination = isset( $_GET["destination"] ) ? $_GET["destination"] : $_POST["destination"];
if ( ! checkPath( $destination ) ) {
$response["status"] = "error";
$response["message"] = "Invalid destination";
exit( json_encode( $response ) );
}
}
//////////////////////////////////////////////////////////////////
// Handle Action
//////////////////////////////////////////////////////////////////
$Filemanager = new Filemanager($_GET, $_POST, $_FILES);
$Filemanager->project = @$_SESSION['project']['path'];
$Filemanager = new Filemanager();
switch( $action ) {
case 'index':
$Filemanager->index();
break;
case 'search':
$Filemanager->search();
break;
case 'find':
$Filemanager->find();
break;
case 'open':
$Filemanager->open();
break;
case 'open_in_browser':
$Filemanager->openinbrowser();
break;
case 'create':
$Filemanager->create();
break;
case 'delete':
$Filemanager->delete();
break;
case 'deleteInner':
$Filemanager->delete( true );
break;
case 'modify':
$Filemanager->modify();
break;
case 'duplicate':
$Filemanager->duplicate();
break;
case 'upload':
$Filemanager->upload();
break;
default:
exit('{"status":"fail","data":{"error":"Unknown Action"}}');
case 'archive':
if( ! isset( $path ) ) {
exit( formatJSEND( "error", "No path specified." ) );
}
if( ! Permissions::check_access( "create", $access ) ) {
exit( formatJSEND( "error", "Invalid access to create archive." ) );
}
$Archive = new Archive();
$path = $Filemanager->formatPath( $path );
$result = $Archive->compress( $path );
if( $result ) {
$response = formatJSEND( "success", null );
} else {
$response = formatJSEND( "error", "Could not create archive." );
}
exit( $response );
break;
case( 'copy' ):
if( isset( $_POST["replace"] ) ) {
$replace = $_POST["replace"];
} else {
$replace = false;
}
$response = $Filemanager->copy( $path, $destination, $replace );
break;
case 'create':
if( isset( $_GET["type"] ) ) {
$type = $_GET["type"];
$response = $Filemanager->create( $path, $type );
} else {
$response["status"] = "error";
$response["message"] = "No filetype set";
}
break;
case 'delete':
$response = $Filemanager->delete( $path, true );
break;
case 'delete_children':
$response = $Filemanager->delete( $path, true, true );
break;
case 'find':
if( ! isset( $_GET["query"] ) ) {
$response["status"] = "error";
$response["message"] = "Missing search query.";
} else {
$query = $_GET["query"];
if( isset( $_GET["options"] ) ) {
$options = $_GET["options"];
}
$response = $Filemanager->find( $path, $query, @$options );
}
break;
case 'index':
$response = $Filemanager->index( $path );
break;
case 'modify':
if( isset( $_POST["data"] ) ) {
$data = json_decode( $_POST["data"], true );
if( json_last_error() !== JSON_ERROR_NONE ) {
$data = json_decode( stripslashes( $_POST["data"] ), true );
}
if( json_last_error() !== JSON_ERROR_NONE ) {
$data = array();
}
if( isset( $data["content"] ) || isset( $data["patch"] ) ) {
$content = isset( $data["content"] ) ? $data["content"] : "";
$patch = isset( $data["patch"] ) ? $data["patch"] : false;
$mtime = isset( $data["mtime"] ) ? $data["mtime"] : 0;
$response = $Filemanager->modify( $path, $content, $patch, $mtime );
} else {
$response["status"] = "error";
$response["message"] = "Missing modification content";
}
} else {
$response["status"] = "error";
$response["message"] = "Missing save data";
}
break;
case 'move':
if( isset( $destination ) ) {
$response = $Filemanager->move( $path, $destination );
} else {
$response["status"] = "error";
$response["message"] = "Missing destination";
}
break;
case 'open':
$response = $Filemanager->open( $path );
break;
case 'preview':
$response = $Filemanager->preview( $path );
break;
case 'rename':
if( isset( $destination ) ) {
$response = $Filemanager->move( $path, $destination );
} else {
$response["status"] = "error";
$response["message"] = "Missing destination";
}
break;
case 'search':
if( isset( $path ) && isset( $_POST["query"] ) ) {
$query = $_POST["query"];
if( isset( $_POST["options"] ) ) {
$options = json_decode( $_POST["options"], true );
} else {
$options = array();
}
$response = $Filemanager->search( $path, $query, $options );
} else {
$response["status"] = "error";
$response["message"] = "Missing search query.";
}
break;
case( "stitch" ):
$response = $Filemanager->stitch( $path );
break;
case 'unarchive':
if( ! isset( $path ) ) {
exit( formatJSEND( "error", "No path specified." ) );
}
if( ! Permissions::check_access( "create", $access ) ) {
exit( formatJSEND( "error", "Invalid access to unzip archive." ) );
}
$Archive = new Archive();
$path = $Filemanager->formatPath( $path );
$result = $Archive->decompress( $path );
if( $result && $result["status"] == "success" ) {
$response = formatJSEND( "success", $result );
} else {
$response = formatJSEND( "error", $result["message"] );
}
exit( $response );
break;
case 'upload_blob':
if( ! isset( $_POST["data"] ) ) {
$response["status"] = "error";
$response["data"] = array(
"error" => "No blob given"
);
exit( json_encode( $response ) );
}
if( ! isset( $_POST["path"] ) ) {
$response["status"] = "error";
$response["data"] = array(
"error" => "No path given"
);
exit( json_encode( $response ) );
}
if( ! isset( $_POST["index"] ) ) {
$response["status"] = "error";
$response["data"] = array(
"error" => "No index given"
);
exit( json_encode( $response ) );
}
$blob = @file_get_contents( $_POST["data"] );
$path = $_POST["path"];
$index = $_POST["index"];
$response = $Filemanager->upload_blob( $path, $index, $blob );
break;
case 'upload_stitch':
$Filemanager->upload_stitch( $path );
break;
default:
$response["status"] = "error";
$response["data"] = array(
"error" => "Unknown action"
);
break;
}
exit( json_encode( $response ) );

View file

@ -14,9 +14,7 @@ require_once('class.filemanager.php');
checkSession();
?>
<form>
<?php
?><form><?php
switch( $_GET['action'] ) {
@ -80,34 +78,54 @@ switch($_GET['action']){
case 'preview':
?>
<label><?php i18n("Inline Preview"); ?></label>
<div><br><br><img src="<?php echo(str_replace(BASE_PATH . "/", "", WORKSPACE) . "/" . $_GET['path']); ?>"><br><br></div>
<button class="btn-right" onclick="codiad.modal.unload();return false;"><?php i18n("Close"); ?></button>
<div>
<?php
break;
//////////////////////////////////////////////////////////////////
// Preview
//////////////////////////////////////////////////////////////////
case 'music_preview':
$path = $_GET['path'];
if( FileManager::isAbsPath( $path ) ) {
$path = FileManager::cleanPath( $path );
} else {
$path = WORKSPACE . "/" . FileManager::cleanPath( $path );
}
$type = mime_content_type( $path );
$source = str_replace( BASE_PATH . "/", "", $path );
if( strpos( $type, "audio" ) !== false ) {
?><audio controls><source src="<?php echo $source;?>"></audio><?php
} elseif( strpos( $type, "image" ) !== false ) {
?><img src="<?php echo $source;?>"><?php
} else {
?><p>Error, unknown file type.</p><?php
}
?>
<label><?php i18n("Inline Preview"); ?></label>
<div><br><br>
<audio controls>
<source src="<?php echo(str_replace(BASE_PATH . "/", "", WORKSPACE) . "/" . $_GET['path']); ?>">
</audio>
<br><br></div>
</div>
<button class="btn-right" onclick="codiad.modal.unload();return false;"><?php i18n("Close");?></button>
<?php
break;
//////////////////////////////////////////////////////////////////
// Overwrite
// replace
//////////////////////////////////////////////////////////////////
case 'overwrite':
case 'replace':
?>
<input type="hidden" name="path" value="<?php echo($_GET['path']); ?>">
<label><?php i18n("Would you like to overwrite or duplicate the following:"); ?></label>
<pre><?php if(!FileManager::isAbsPath($_GET['path'])) { echo '/'; }; echo($_GET['path']); ?></pre>
<label><?php i18n("Would you like to replace or duplicate the following:"); ?></label>
<pre>
<?php
if( ! FileManager::isAbsPath( $_GET['path'] ) ) {
echo '/';
};
echo( $_GET['path'] );
?>
</pre>
<select name="or_action">
<option value="0"><?php i18n("Overwrite Original"); ?></option>
<option value="1"><?php i18n("Create Duplicate"); ?></option>
@ -134,9 +152,12 @@ switch($_GET['action']){
<label><?php i18n("In:"); ?></label>
<select name="search_type">
<option value="0"><?php i18n("Current Project"); ?></option>
<?php if(checkAccess()) { ?>
<option value="1"><?php i18n("Workspace Projects"); ?></option>
<?php } ?>
<?php
if( checkAccess() ) {
?><option value="1"><?php i18n("Workspace Projects"); ?></option><?php
}
?>
</select>
</td>
</tr>
@ -154,7 +175,25 @@ switch($_GET['action']){
<?php
break;
}
case 'selector':
?>
</form>
<div>
<div id="modal-loading" style="display: inline-block;vertical-align: middle;min-width:25px;"></div>
<div style="display: inline-block;vertical-align: middle;">Loading File Selector ...</div>
</div>
<?php
break;
case 'upload':
?>
<div>
<div id="modal-loading" style="display: inline-block;vertical-align: middle;min-width:25px;"></div>
<div style="display: inline-block;vertical-align: middle;">Loading Uploader ...</div>
</div>
<?php
break;
}
?></form>

View file

@ -1,58 +0,0 @@
<?php
/*
* Copyright (c) Codiad & Kent Safranski (codiad.com), distributed
* as-is and without warranty under the MIT License. See
* [root]/license.txt for more. This information must remain intact.
*/
require_once('../../common.php');
require_once('class.filemanager.php');
//////////////////////////////////////////////////////////////////
// Verify Session or Key
//////////////////////////////////////////////////////////////////
checkSession();
?>
<label><?php i18n("Upload Files"); ?></label>
<div id="upload-drop-zone">
<span id="upload-wrapper">
<input id="fileupload" type="file" name="upload[]" data-url="components/filemanager/controller.php?action=upload&path=<?php echo($_GET['path']); ?>" multiple>
<span id="upload-clicker"><?php i18n("Drag Files or Click Here to Upload"); ?></span>
</span>
<div id="upload-progress"><div class="bar"></div></div>
<div id="upload-complete"><?php i18n("Complete!"); ?></div>
</div>
<button onclick="codiad.modal.unload();"><?php i18n("Close Uploader"); ?></button>
<script>
$(function () {
$('#fileupload').fileupload({
dataType: 'json',
dropZone: '#upload-drop-zone',
progressall: function( e, data ) {
var progress = parseInt(data.loaded / data.total * 100, 10);
$('#upload-progress .bar').css(
'width',
progress + '%'
);
if(progress>98){ $('#upload-complete').fadeIn(200); }
},
done: function(e, data){
$.each(data.result, function (index, file){
var path = '<?php echo($_GET['path']); ?>';
codiad.filemanager.createObject(path, path + "/" + file.name,'file');
/* Notify listeners. */
amplify.publish('filemanager.onUpload', {file: file, path: path});
});
setTimeout(function(){
$('#upload-progress .bar').animate({'width':0},700);
$('#upload-complete').fadeOut(200);
},1000);
}
});
});
</script>

View file

@ -7,6 +7,7 @@
*/
require_once( '../../common.php' );
require_once( './class.archive.php' );
//////////////////////////////////////////////////////////////////
// Verify Session or Key
@ -14,71 +15,95 @@
checkSession();
//////////////////////////////////////////////////////////////////
// Check $_GET for invalid path
//////////////////////////////////////////////////////////////////
//TODO check if the User is allowed to access the project
if (!isset($_GET['path'])
|| preg_match('#^[\\\/]?$#i', trim($_GET['path'])) // download all Projects
|| preg_match('#[\:*?\"<>\|]#i', $_GET['path']) //illegal chars in filenames
|| substr_count($_GET['path'], './') > 0) { // change directory up to escape Workspace
exit('<script>parent.codiad.message.error("Wrong data send")</script>');
$response = array(
"status" => "none",
"message" => null,
);
if( ! isset( $_GET["path"] ) && ! isset( $_POST["path"] ) ) {
$response["status"] = "error";
$response["message"] = "Missing path.";
exit( json_encode( $response ) );
}
//////////////////////////////////////////////////////////////////
// Run Download
//////////////////////////////////////////////////////////////////
$path = ( isset( $_GET["path"] ) ) ? $_GET["path"] : $_POST["path"];
$full_path = "";
if (isset($_GET['type']) && ($_GET['type']=='directory' || $_GET['type']=='root')) {
// Create tarball
$filename = explode("/", $_GET['path']);
//$filename = array_pop($filename) . "-" . date('Y.m.d') . ".tar.gz";
$filename = array_pop($filename) . "-" . date('Y.m.d');
$targetPath = DATA . '/';
$dir = WORKSPACE . '/' . $_GET['path'];
if (!is_dir($dir)) {
exit('<script>parent.codiad.message.error("Directory not found.")</script>');
}
if( Common::isAbsPath( $path ) ) {
//////////////////////////////////////////////////////////////////
// Check system() command and a non windows OS
//////////////////////////////////////////////////////////////////
if (extension_loaded('zip')) { //Check if zip-Extension is availiable
//build zipfile
require_once 'class.dirzip.php';
$filename .= '.zip';
$download_file = $targetPath.$filename;
DirZip::zipDir($dir, $targetPath .$filename);
} elseif (isAvailable('system') && stripos(PHP_OS, 'win') === false) {
# Execute the tar command and save file
$filename .= '.tar.gz';
system("tar -pczf ".escapeshellarg($targetPath.$filename)." -C ".escapeshellarg(WORKSPACE)." ".escapeshellarg($_GET['path']));
$download_file = $targetPath.$filename;
$full_path = realpath( $path );
} else {
exit('<script>parent.codiad.message.error("Could not pack the folder, zip-extension missing")</script>');
$full_path = WORKSPACE . "/$path";
$full_path = realpath( $full_path );
}
} else {
$filename = explode("/", $_GET['path']);
$filename = array_pop($filename);
$download_file = WORKSPACE . '/' . $_GET['path'];
if( $full_path === false ) {
$response["status"] = "error";
$response["message"] = "Invalid path.";
exit( json_encode( $response ) );
}
if( ! Permissions::has_read( $path ) ) {
$response["status"] = "error";
$response["message"] = "You do not have access to this path.";
exit( json_encode( $response ) );
}
if( is_dir( $full_path ) ) {
$temp_path = tempnam( sys_get_temp_dir(), 'codiad_download_' . date( "U" ) );
$result = Archive::compress( $full_path, $temp_path, 'default' );
$mime_type = mime_content_type( $temp_path );
if( in_array( $mime_type, array_keys( Archive::MIME_TYPE_EXTENSIONS ) ) ) {
$extension = Archive::MIME_TYPE_EXTENSIONS["$mime_type"];
}
if( $result ) {
header( 'Content-Description: File Transfer' );
header( 'Content-Type: application/octet-stream' );
header('Content-Disposition: attachment; filename="'.basename($filename).'"');
header( 'Content-Disposition: attachment; filename="' . basename( $full_path ) . ".$extension" . '"' );
header( 'Content-Transfer-Encoding: binary' );
header( 'Expires: 0' );
header( 'Cache-Control: must-revalidate' );
header( 'Pragma: public' );
header('Content-Length: ' . filesize($download_file));
header( 'Content-Length: ' . filesize( $temp_path ) );
if( ob_get_contents() ) {
ob_end_clean();
}
flush();
readfile($download_file);
// Remove temp tarball
if ($_GET['type']=='directory' || $_GET['type']=='root') {
unlink($download_file);
file_put_contents( "php://output", file_get_contents( $temp_path ) );
} else {
$response["status"] = "error";
$response["message"] = "An archive could not be created.";
}
unlink( $temp_path );
} else {
header( 'Content-Description: File Transfer' );
header( 'Content-Type: application/octet-stream' );
header( 'Content-Disposition: attachment; filename="' . basename( $full_path ) . '"' );
header( 'Content-Transfer-Encoding: binary' );
header( 'Expires: 0' );
header( 'Cache-Control: must-revalidate' );
header( 'Pragma: public' );
header( 'Content-Length: ' . filesize( $full_path ) );
if( ob_get_contents() ) {
ob_end_clean();
}
flush();
readfile( $full_path );
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,172 +0,0 @@
/*
* jQuery Iframe Transport Plugin 1.5
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2011, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* http://www.opensource.org/licenses/MIT
*/
/*jslint unparam: true, nomen: true */
/*global define, window, document */
(function (factory) {
'use strict';
if (typeof define === 'function' && define.amd) {
// Register as an anonymous AMD module:
define(['jquery'], factory);
} else {
// Browser globals:
factory(window.jQuery);
}
}(function ($) {
'use strict';
// Helper variable to create unique names for the transport iframes:
var counter = 0;
// The iframe transport accepts three additional options:
// options.fileInput: a jQuery collection of file input fields
// options.paramName: the parameter name for the file form data,
// overrides the name property of the file input field(s),
// can be a string or an array of strings.
// options.formData: an array of objects with name and value properties,
// equivalent to the return data of .serializeArray(), e.g.:
// [{name: 'a', value: 1}, {name: 'b', value: 2}]
$.ajaxTransport('iframe', function (options) {
if (options.async && (options.type === 'POST' || options.type === 'GET')) {
var form,
iframe;
return {
send: function (_, completeCallback) {
form = $('<form style="display:none;"></form>');
form.attr('accept-charset', options.formAcceptCharset);
// javascript:false as initial iframe src
// prevents warning popups on HTTPS in IE6.
// IE versions below IE8 cannot set the name property of
// elements that have already been added to the DOM,
// so we set the name along with the iframe HTML markup:
iframe = $(
'<iframe src="javascript:false;" name="iframe-transport-' +
(counter += 1) + '"></iframe>'
).bind('load', function () {
var fileInputClones,
paramNames = $.isArray(options.paramName) ?
options.paramName : [options.paramName];
iframe
.unbind('load')
.bind('load', function () {
var response;
// Wrap in a try/catch block to catch exceptions thrown
// when trying to access cross-domain iframe contents:
try {
response = iframe.contents();
// Google Chrome and Firefox do not throw an
// exception when calling iframe.contents() on
// cross-domain requests, so we unify the response:
if (!response.length || !response[0].firstChild) {
throw new Error();
}
} catch (e) {
response = undefined;
}
// The complete callback returns the
// iframe content document as response object:
completeCallback(
200,
'success',
{'iframe': response}
);
// Fix for IE endless progress bar activity bug
// (happens on form submits to iframe targets):
$('<iframe src="javascript:false;"></iframe>')
.appendTo(form);
form.remove();
});
form
.prop('target', iframe.prop('name'))
.prop('action', options.url)
.prop('method', options.type);
if (options.formData) {
$.each(options.formData, function (index, field) {
$('<input type="hidden"/>')
.prop('name', field.name)
.val(field.value)
.appendTo(form);
});
}
if (options.fileInput && options.fileInput.length &&
options.type === 'POST') {
fileInputClones = options.fileInput.clone();
// Insert a clone for each file input field:
options.fileInput.after(function (index) {
return fileInputClones[index];
});
if (options.paramName) {
options.fileInput.each(function (index) {
$(this).prop(
'name',
paramNames[index] || options.paramName
);
});
}
// Appending the file input fields to the hidden form
// removes them from their original location:
form
.append(options.fileInput)
.prop('enctype', 'multipart/form-data')
// enctype must be set as encoding for IE:
.prop('encoding', 'multipart/form-data');
}
form.submit();
// Insert the file input fields at their original location
// by replacing the clones with the originals:
if (fileInputClones && fileInputClones.length) {
options.fileInput.each(function (index, input) {
var clone = $(fileInputClones[index]);
$(input).prop('name', clone.prop('name'));
clone.replaceWith(input);
});
}
});
form.append(iframe).appendTo(document.body);
},
abort: function () {
if (iframe) {
// javascript:false as iframe src aborts the request
// and prevents warning popups on HTTPS in IE6.
// concat is used to avoid the "Script URL" JSLint error:
iframe
.unbind('load')
.prop('src', 'javascript'.concat(':false;'));
}
if (form) {
form.remove();
}
}
};
}
});
// The iframe transport returns the iframe content document as response.
// The following adds converters from iframe to text, json, html, and script:
$.ajaxSetup({
converters: {
'iframe text': function (iframe) {
return $(iframe[0].body).text();
},
'iframe json': function (iframe) {
return $.parseJSON($(iframe[0].body).text());
},
'iframe html': function (iframe) {
return $(iframe[0].body).html();
},
'iframe script': function (iframe) {
return $.globalEval($(iframe[0].body).text());
}
}
});
}));

View file

@ -1,282 +0,0 @@
/*
* jQuery UI Widget 1.8.23+amd
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* http://docs.jquery.com/UI/Widget
*/
(function (factory) {
if (typeof define === "function" && define.amd) {
// Register as an anonymous AMD module:
define(["jquery"], factory);
} else {
// Browser globals:
factory(jQuery);
}
}(function( $, undefined ) {
// jQuery 1.4+
if ( $.cleanData ) {
var _cleanData = $.cleanData;
$.cleanData = function( elems ) {
for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
try {
$( elem ).triggerHandler( "remove" );
// http://bugs.jquery.com/ticket/8235
} catch( e ) {}
}
_cleanData( elems );
};
} else {
var _remove = $.fn.remove;
$.fn.remove = function( selector, keepData ) {
return this.each(function() {
if ( !keepData ) {
if ( !selector || $.filter( selector, [ this ] ).length ) {
$( "*", this ).add( [ this ] ).each(function() {
try {
$( this ).triggerHandler( "remove" );
// http://bugs.jquery.com/ticket/8235
} catch( e ) {}
});
}
}
return _remove.call( $(this), selector, keepData );
});
};
}
$.widget = function( name, base, prototype ) {
var namespace = name.split( "." )[ 0 ],
fullName;
name = name.split( "." )[ 1 ];
fullName = namespace + "-" + name;
if ( !prototype ) {
prototype = base;
base = $.Widget;
}
// create selector for plugin
$.expr[ ":" ][ fullName ] = function( elem ) {
return !!$.data( elem, name );
};
$[ namespace ] = $[ namespace ] || {};
$[ namespace ][ name ] = function( options, element ) {
// allow instantiation without initializing for simple inheritance
if ( arguments.length ) {
this._createWidget( options, element );
}
};
var basePrototype = new base();
// we need to make the options hash a property directly on the new instance
// otherwise we'll modify the options hash on the prototype that we're
// inheriting from
// $.each( basePrototype, function( key, val ) {
// if ( $.isPlainObject(val) ) {
// basePrototype[ key ] = $.extend( {}, val );
// }
// });
basePrototype.options = $.extend( true, {}, basePrototype.options );
$[ namespace ][ name ].prototype = $.extend( true, basePrototype, {
namespace: namespace,
widgetName: name,
widgetEventPrefix: $[ namespace ][ name ].prototype.widgetEventPrefix || name,
widgetBaseClass: fullName
}, prototype );
$.widget.bridge( name, $[ namespace ][ name ] );
};
$.widget.bridge = function( name, object ) {
$.fn[ name ] = function( options ) {
var isMethodCall = typeof options === "string",
args = Array.prototype.slice.call( arguments, 1 ),
returnValue = this;
// allow multiple hashes to be passed on init
options = !isMethodCall && args.length ?
$.extend.apply( null, [ true, options ].concat(args) ) :
options;
// prevent calls to internal methods
if ( isMethodCall && options.charAt( 0 ) === "_" ) {
return returnValue;
}
if ( isMethodCall ) {
this.each(function() {
var instance = $.data( this, name ),
methodValue = instance && $.isFunction( instance[options] ) ?
instance[ options ].apply( instance, args ) :
instance;
// TODO: add this back in 1.9 and use $.error() (see #5972)
// if ( !instance ) {
// throw "cannot call methods on " + name + " prior to initialization; " +
// "attempted to call method '" + options + "'";
// }
// if ( !$.isFunction( instance[options] ) ) {
// throw "no such method '" + options + "' for " + name + " widget instance";
// }
// var methodValue = instance[ options ].apply( instance, args );
if ( methodValue !== instance && methodValue !== undefined ) {
returnValue = methodValue;
return false;
}
});
} else {
this.each(function() {
var instance = $.data( this, name );
if ( instance ) {
instance.option( options || {} )._init();
} else {
$.data( this, name, new object( options, this ) );
}
});
}
return returnValue;
};
};
$.Widget = function( options, element ) {
// allow instantiation without initializing for simple inheritance
if ( arguments.length ) {
this._createWidget( options, element );
}
};
$.Widget.prototype = {
widgetName: "widget",
widgetEventPrefix: "",
options: {
disabled: false
},
_createWidget: function( options, element ) {
// $.widget.bridge stores the plugin instance, but we do it anyway
// so that it's stored even before the _create function runs
$.data( element, this.widgetName, this );
this.element = $( element );
this.options = $.extend( true, {},
this.options,
this._getCreateOptions(),
options );
var self = this;
this.element.bind( "remove." + this.widgetName, function() {
self.destroy();
});
this._create();
this._trigger( "create" );
this._init();
},
_getCreateOptions: function() {
return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ];
},
_create: function() {},
_init: function() {},
destroy: function() {
this.element
.unbind( "." + this.widgetName )
.removeData( this.widgetName );
this.widget()
.unbind( "." + this.widgetName )
.removeAttr( "aria-disabled" )
.removeClass(
this.widgetBaseClass + "-disabled " +
"ui-state-disabled" );
},
widget: function() {
return this.element;
},
option: function( key, value ) {
var options = key;
if ( arguments.length === 0 ) {
// don't return a reference to the internal hash
return $.extend( {}, this.options );
}
if (typeof key === "string" ) {
if ( value === undefined ) {
return this.options[ key ];
}
options = {};
options[ key ] = value;
}
this._setOptions( options );
return this;
},
_setOptions: function( options ) {
var self = this;
$.each( options, function( key, value ) {
self._setOption( key, value );
});
return this;
},
_setOption: function( key, value ) {
this.options[ key ] = value;
if ( key === "disabled" ) {
this.widget()
[ value ? "addClass" : "removeClass"](
this.widgetBaseClass + "-disabled" + " " +
"ui-state-disabled" )
.attr( "aria-disabled", value );
}
return this;
},
enable: function() {
return this._setOption( "disabled", false );
},
disable: function() {
return this._setOption( "disabled", true );
},
_trigger: function( type, event, data ) {
var prop, orig,
callback = this.options[ type ];
data = data || {};
event = $.Event( event );
event.type = ( type === this.widgetEventPrefix ?
type :
this.widgetEventPrefix + type ).toLowerCase();
// the original event may come from any element
// so we need to reset the target on the new event
event.target = this.element[ 0 ];
// copy original event properties over to the new event
orig = event.originalEvent;
if ( orig ) {
for ( prop in orig ) {
if ( !( prop in event ) ) {
event[ prop ] = orig[ prop ];
}
}
}
this.element.trigger( event, data );
return !( $.isFunction(callback) &&
callback.call( this.element[0], event, data ) === false ||
event.isDefaultPrevented() );
}
};
}));

View file

@ -5,6 +5,8 @@ require_once( __DIR__ . "/../settings/class.settings.php" );
class Install {
const PATH_REGEX = '/[^\w\-\._@]/';
public $active = "";
public $config = "";
public $db_types = array();
@ -84,7 +86,7 @@ class Install {
function clean_username( $username ) {
return strtolower( preg_replace( '/[^\w\-\._@]/', '-', $username ) );
return strtolower( preg_replace( self::PATH_REGEX, '-', $username ) );
}
function create_config() {
@ -148,20 +150,22 @@ define("WSURL", BASE_URL . "/workspace");
// Marketplace
//define("MARKETURL", "http://market.codiad.com/json");
';
$this->save_file( $this->config, $config_data );
echo( "success" );
return file_put_contents( $this->config, $config_data );
}
function create_project() {
$project_path = $this->project_path;
$connection = $this->sql->connect();
if ( ! $this->is_abs_path( $project_path ) ) {
$project_path = preg_replace( '/[^\w-._@]/', '-', $project_path );
$project_path = preg_replace( self::PATH_REGEX, '-', $project_path );
$project_path = $this->username . "/" . $project_path;
if( ! is_dir( $this->workspace . "/" . $project_path ) ) {
mkdir( $this->workspace . "/" . $project_path );
mkdir( $this->workspace . "/" . $project_path, 0755, true );
}
} else {
@ -184,57 +188,52 @@ define("WSURL", BASE_URL . "/workspace");
}
}
$query = "DELETE FROM projects WHERE path = ?;";
$bind_variables = array(
$project_path
);
$statement = $connection->prepare( $query );
$statement->execute( $bind_variables );
$query = "INSERT INTO projects(name, path, owner) VALUES (?,?,( SELECT id FROM users WHERE username = ? LIMIT 1 ));";
$bind_variables = array(
$this->project_name,
$project_path,
$this->username
);
$query = "INSERT INTO projects(name, path, owner) VALUES (?,?,?);";
$connection = $this->sql->connect();
$statement = $connection->prepare( $query );
$statement->execute( $bind_variables );
$error = $statement->errorInfo();
if( ! $error[0] == "00000" ) {
die( '{"message":"Could not create project in database.","error":"' . addslashes(json_encode( $error )) .'"}' );
}
}
function create_tables() {
$result = $this->sql->create_default_tables();
if ( ! $result === true ) {
if ( ! $result["create_tables"] === true ) {
die( '{"message":"Could not tables in database.","error":"' . json_encode( $result ) .'"}' );
exit( json_encode( $result ) );
}
}
function create_user() {
$bind_variables = array(
"",
"",
$this->username,
$this->password,
"",
$this->project_path,
"admin",
"",
""
Permissions::LEVELS["admin"]
);
$query = "INSERT INTO users(first_name, last_name, username, password, email, project, access, groups, token) VALUES (?,?,?,?,?,?,?,?,?)";
$query = "INSERT INTO users( username, password, project, access ) VALUES ( ?,?,( SELECT id FROM projects WHERE path = ? LIMIT 1 ),? )";
try {
$connection = $this->sql->connect();
$statement = $connection->prepare( $query );
$statement->execute( $bind_variables );
$error = $statement->errorInfo();
} catch( exception $e ) {
if( ! $error[0] == "00000" ) {
die( '{"message":"Could not create user in database.","error":"' . addslashes(json_encode( $error )) .'"}' );
exit( "Error could not create user: " . $e->getMessage() );
}
$this->set_default_options();
}
@ -269,10 +268,11 @@ define("WSURL", BASE_URL . "/workspace");
$connection = $this->sql->connect();
$this->create_tables();
$this->create_project();
$this->create_user();
$this->create_project();
//exit( "stop" );
$this->create_config();
return "success";
}
function JSEND( $message, $error=null ) {
@ -288,18 +288,14 @@ define("WSURL", BASE_URL . "/workspace");
exit( json_encode( $message ) );
}
function save_file( $file, $data ) {
$write = fopen( $file, 'w' ) or die( '{"message": "can\'t open file"}' );
fwrite( $write, $data );
fclose( $write );
}
public function set_default_options() {
foreach( Settings::DEFAULT_OPTIONS as $id => $option ) {
$query = "INSERT INTO user_options ( name, username, value ) VALUES ( ?, ?, ? );";
$query = array(
"*" => "INSERT INTO user_options ( name, user, value ) VALUES ( ?, ( SELECT id FROM users WHERE username = ? ), ? );",
"pgsql" => 'INSERT INTO user_options ( name, "user", value ) VALUES ( ?, ( SELECT id FROM users WHERE username = ? ), ? );',
);
$bind_variables = array(
$option["name"],
$this->username,
@ -309,7 +305,10 @@ define("WSURL", BASE_URL . "/workspace");
if( $result == 0 ) {
$query = "UPDATE user_options SET value=? WHERE name=? AND username=?;";
$query = array(
"*" => "UPDATE user_options SET value=? WHERE name=? AND user=( SELECT id FROM users WHERE username = ? );",
"pgsql" => 'UPDATE user_options SET value=? WHERE name=? AND "user"=( SELECT id FROM users WHERE username = ? );',
);
$bind_variables = array(
$option["value"],
$option["name"],

View file

@ -442,12 +442,12 @@ if(!password_match){ alert('The passwords entered do not match'); }
if(!empty_fields && password_match && check_path){
$.post('components/install/install.php',$('#install').serialize(),function( data ) {
if( data == 'success' ){
console.log( data );
if( data === "success" || data == "" ){
window.location.reload();
} else {
data = JSON.parse( data );
console.log( data.error );
alert( "An Error Occurred\n" + data.message );
alert( "An Error Occurred. Please check the console for more information.\n" );
}
});
}

View file

@ -39,6 +39,63 @@
codiad.keybindings = {
bindings: [
{
name: 'Find',
bindKey: {
win: 'Ctrl-F',
mac: 'Command-F'
},
exec: function( e ) {
codiad.editor.openSearch( 'find' );
}
},
{
name: 'Goto Line',
bindKey: {
win: 'Ctrl-L',
mac: 'Command-L'
},
exec: function( e ) {
codiad.editor.open_goto();
}
},
{
name: 'Move Down',
bindKey: {
win: 'Ctrl-down',
mac: 'Command-up'
},
exec: function( e ) {
codiad.active.move( 'down' );
}
},
{
name: 'Move Up',
bindKey: {
win: 'Ctrl-up',
mac: 'Command-up'
},
exec: function( e ) {
codiad.active.move( 'up' );
}
},
{
name: 'Replace',
bindKey: {
win: 'Ctrl-R',
mac: 'Command-R'
},
exec: function( e ) {
codiad.editor.openSearch( 'replace' );
}
}
],
init: function() {
// Active List Next [CTRL+DOWN] //////////////////////////////
@ -74,6 +131,12 @@
codiad.editor.openSearch( 'find' );
});
// Find [CTRL+L] /////////////////////////////////////////////
$.ctrl( '76', function() {
codiad.editor.open_goto();
});
// Open in browser [CTRL+O] //////////////////////////////////
$.ctrl( '79', function() {

View file

@ -224,7 +224,7 @@ class Market extends Common
}
} else {
$reponame = explode('/', $repo);
$tmp = file_get_contents($this->url.'/?t='.rtrim($type, "s").'&i='.str_replace("-master", "", $reponame[sizeof($repo)-1]));
$tmp = file_get_contents($this->url.'/?t='.rtrim($type, "s").'&i='.str_replace("-master", "", $reponame[@sizeof($repo)-1]));
}
if (file_put_contents(BASE_PATH.'/'.$type.'/'.$name.'.zip', fopen($repo.'/archive/master.zip', 'r'))) {
$zip = new ZipArchive;

View file

@ -0,0 +1,168 @@
<?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.
*/
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
class Permissions {
const LEVELS = array(
"none" => 0,
"read" => 1,
"write" => 2,
"create" => 4,
"delete" => 8,
"manager" => 16,
"owner" => 32,
"admin" => 64,
);
const SYSTEM_LEVELS = array(
"user" => 32,
"admin" => 64,
);
function __construct() {
}
public static function check_access( $level, $user_level ) {
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." ) );
}
} else {
if( ! in_array( $level, self::LEVELS ) ) {
exit( formatJSEND( "error", "Access Level does not exist." ) );
}
}
return ( $user_level >= $level );
}
public static function check_path( $level, $path ) {
$user_level = self::get_access( $path );
return self::check_access( $level, $user_level );
}
public static function get_access( $path ) {
global $sql;
$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() );
if( ! empty( $projects ) ) {
foreach( $projects as $row => $data ) {
$full_project_path = Common::isAbsPath( $data["path"] ) ? $data["path"] : WORKSPACE . "/{$data["path"]}";
$path_postition = strpos( $full_path, $full_project_path );
if( $path_postition === false ) {
continue;
}
if( $data["owner"] == -1 ) {
$access = self::LEVELS["owner"];
} elseif( $data["owner"] == $_SESSION["user_id"] ) {
$access = self::LEVELS["owner"];
} else {
$user = $sql->query( array(
"*" => "SELECT * FROM access WHERE project = ? AND user = ? LIMIT 1",
"pgsql" => '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"], $data["owner"], $_SESSION["user"] );
if( $access > 0 ) {
break;
}
}
}
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 ) {
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

@ -7,6 +7,7 @@
*/
require_once( '../../common.php' );
require_once( '../filemanager/class.filemanager.php' );
class Project extends Common {
@ -14,6 +15,7 @@ class Project extends Common {
// PROPERTIES
//////////////////////////////////////////////////////////////////
public $access = Permissions::LEVELS["read"];
public $name = '';
public $path = '';
public $gitrepo = false;
@ -22,7 +24,6 @@ class Project extends Common {
public $no_return = false;
public $assigned = false;
public $command_exec = '';
public $public_project = false;
public $user = '';
//////////////////////////////////////////////////////////////////
@ -43,68 +44,100 @@ class Project extends Common {
// NEW METHODS
//////////////////////////////////////////////////////////////////
public function add_project( $project_name, $project_path, $owner = null ) {
public function add_project( $project_name, $project_path, $owner ) {
global $sql;
if( $this->public_project ) {
$owner = 'nobody';
} else {
$owner = $_SESSION["user"];
}
$query = "INSERT INTO projects( name, path, owner ) VALUES ( ?, ?, ? );";
$bind_variables = array( $project_name, $project_path, $owner );
$return = $sql->query( $query, $bind_variables, 0, "rowCount" );
if( ! ( $return > 0 ) ) {
exit( formatJSEND( "error", "Error creating project $project_name" ) );
}
return $return;
}
public function add_user() {
public function add_user( $path, $user_id, $access ) {
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];
$return = array(
"status" => null,
"message" => null,
);
$query = "SELECT * FROM projects WHERE path=? AND owner=? LIMIT 1";
$bind_variables = array( $path, $_SESSION["user_id"] );
$project = $sql->query( $query, $bind_variables, array(), "fetch" );
if( ! empty( $result ) ) {
if( empty( $project ) ) {
$access = json_decode( $result["access"] );
if( is_array( $access ) ) {
if( ! in_array( $this->user, $access ) ) {
array_push( $access, $this->user );
}
$return["status"] = "error";
$return["message"] = "Error fetching projects.";
} else {
$access = array(
$this->user
);
}
$user = $sql->query( array(
"*" => "SELECT * FROM access WHERE project = ? AND user = ? LIMIT 1",
"pgsql" => 'SELECT * FROM access WHERE project = ? AND "user" = ? LIMIT 1',
), array( $project["id"], $user_id ), array(), "fetch" );
$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( ! empty( $user ) ) {
$query = array(
"*" => "UPDATE access SET level=? WHERE project=? AND user=?;",
"pgsql" => 'UPDATE access SET level=? WHERE project=? AND "user"=?;',
);
$bind_variables = array( $access, $project["id"], $user_id );
$result = $sql->query( $query, $bind_variables, 0, "rowCount" );
if( $result > 0 ) {
echo( formatJSEND( "success", "Successfully added {$this->user}." ) );
$return["status"] = "success";
$return["message"] = "Successfully updated access.";
} else {
echo formatJSEND( "error", "Error setting access for project." );
$return["status"] = "error";
$return["message"] = "Error setting access for project.";
}
} else {
echo formatJSEND( "error", "Error fetching projects." );
$query = array(
"*" => "INSERT INTO access ( project, user, level ) VALUES ( ?,?,? );",
"pgsql" => 'INSERT INTO access ( project, "user", level ) VALUES ( ?,?,? );',
);
$bind_variables = array( $project["id"], $user_id, $access );
$result = $sql->query( $query, $bind_variables, 0, "rowCount", "exception" );
if( $result > 0 ) {
$return["status"] = "success";
$return["message"] = "Successfully updated access.";
} else {
$return["status"] = "error";
$return["message"] = "Error setting access for project.";
}
}
}
return $return;
}
public function check_duplicate( $full_path ) {
global $sql;
$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 ) {
@ -115,7 +148,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 ) ) {
@ -123,13 +156,13 @@ class Project extends Common {
$owner = $result["owner"];
if( $exclude_public ) {
if( $owner == $_SESSION["user"] ) {
if( $owner == $_SESSION["user_id"] ) {
$return = true;
}
} else {
if( $owner == $_SESSION["user"] || $owner == 'nobody' ) {
if( $owner == $_SESSION["user_id"] || $owner == 'nobody' ) {
$return = true;
}
@ -138,25 +171,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 );
}
@ -169,7 +189,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 ) ) {
@ -188,63 +208,97 @@ class Project extends Common {
$project = $this->path;
}
global $sql;
$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];
$query = array(
"*" => "
SELECT * FROM projects
WHERE path = ?
AND (
owner=?
OR owner=-1
OR id IN ( SELECT project FROM access WHERE user = ? )
) ORDER BY name;
",
"pgsql" => '
SELECT * FROM projects
WHERE path = ?
AND (
owner=?
OR owner=-1
OR id IN ( SELECT project FROM access WHERE "user" = ? )
) ORDER BY name;
',
);
$bind_variables = array( $project, $_SESSION["user_id"], $_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(), "fetch" );
if( ! empty( $return ) ) {
} else {
$return = formatJSEND( "error", "Error fetching projects." );
$return = formatJSEND( "error", "No projects found." );
}
return( $return );
}
public function get_all_projects() {
if( is_admin() ) {
global $sql;
$query = "SELECT * FROM projects";
$bind_variables = array();
$return = $sql->query( $query, $bind_variables, array() );
if( empty( $return ) ) {
$return = formatJSEND( "error", "No projects found." );
}
} else {
$return = formatJSEND( "error", "Only admins are allowed to view all projects." );
}
return( $return );
}
public function get_projects() {
global $sql;
$query = "SELECT * FROM projects WHERE owner=? OR owner='nobody' OR access LIKE ? ORDER BY name;";
$bind_variables = array( $_SESSION["user"], '%"' . $_SESSION["user"] . '"%' );
$query = array(
"*" => "SELECT * FROM projects
WHERE owner=?
OR owner=-1
OR id IN ( SELECT project FROM access WHERE user = ? );
",
"pgsql" => 'SELECT * FROM projects
WHERE owner=?
OR owner=-1
OR id IN ( SELECT project FROM access WHERE "user" = ? );
',
);
$bind_variables = array( $_SESSION["user_id"], $_SESSION["user_id"] );
$return = $sql->query( $query, $bind_variables, array() );
if( empty( $return ) ) {
$return = formatJSEND( "error", "Error fetching projects." );
}
return( $return );
}
public function remove_user() {
public function remove_user( $user_id ) {
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 ) ) {
if( $user_id === false ) {
$access = json_decode( $result["access"] );
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." ) );
}
return formatJSEND( "error", "Error fetching user information." );
}
$access = json_encode( $access );
$query = "UPDATE projects SET access=? WHERE path=? AND owner=?;";
$bind_variables = array( $access, $this->path, $_SESSION["user"] );
$query = array(
"*" => "DELETE FROM access WHERE project=? AND user=?;",
"pgsql" => '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 ) {
@ -252,26 +306,22 @@ class Project extends Common {
echo( formatJSEND( "success", "Successfully removed {$this->user}." ) );
} else {
echo formatJSEND( "error", "Error setting access for project." );
}
} else {
echo formatJSEND( "error", "Error fetching projects." );
echo( formatJSEND( "error", "{$this->user} is not in the access list." ) );
}
}
public function rename_project( $old_name, $new_name, $path ) {
global $sql;
$query = "SELECT * FROM projects WHERE name=? AND path=? AND ( owner=? OR owner='nobody' );";
$bind_variables = array( $old_name, $path, $_SESSION["user"] );
$query = "SELECT * FROM projects WHERE name=? AND path=? AND ( owner=? OR owner=-1 );";
$bind_variables = array( $old_name, $path, $_SESSION["user_id"] );
$return = $sql->query( $query, $bind_variables, array() );
$pass = false;
if( ! empty( $return ) ) {
$query = "UPDATE projects SET name=? WHERE name=? AND path=? AND ( owner=? OR owner='nobody' );";
$bind_variables = array( $new_name, $old_name, $path, $_SESSION["user"] );
$query = "UPDATE projects SET name=? WHERE name=? AND path=? AND ( owner=? OR owner=-1 );";
$bind_variables = array( $new_name, $old_name, $path, $_SESSION["user_id"] );
$return = $sql->query( $query, $bind_variables, 0, "rowCount");
if( $return > 0 ) {
@ -302,16 +352,17 @@ class Project extends Common {
public function GetFirst() {
if( ! is_array( $this->projects ) || empty( $this->projects ) ) {
return null;
}
$this->name = $this->projects[0]['name'];
$this->path = $this->projects[0]['path'];
// Set Sessions
$_SESSION['project'] = $this->path;
if ( ! $this->no_return ) {
echo formatJSEND( "success", $this->projects[0] );
}
return $this->projects[0];
}
//////////////////////////////////////////////////////////////////
@ -337,17 +388,35 @@ class Project extends Common {
public function Open() {
global $sql;
$query = "SELECT * FROM projects WHERE path=? AND ( owner=? OR owner='nobody' OR access LIKE ? );";
$bind_variables = array( $this->path, $_SESSION["user"], '%"' . $_SESSION["user"] . '"%' );
$return = $sql->query( $query, $bind_variables, array() )[0];
$query = array(
"*" => "SELECT * FROM projects
WHERE path = ?
AND (
owner=?
OR owner=-1
OR id IN ( SELECT project FROM access WHERE user = ? )
) ORDER BY name LIMIT 1;
",
"pgsql" => 'SELECT * FROM projects
WHERE path = ?
AND (
owner=?
OR owner=-1
OR id IN ( SELECT project FROM access WHERE "user" = ? )
) ORDER BY name LIMIT 1;
',
);
$bind_variables = array( $this->path, $_SESSION["user_id"], $_SESSION["user_id"] );
$return = $sql->query( $query, $bind_variables, array(), "fetch" );
if( ! empty( $return ) ) {
$query = "UPDATE users SET project=? WHERE username=?;";
$bind_variables = array( $this->path, $_SESSION["user"] );
$bind_variables = array( $return["id"], $_SESSION["user"] );
$sql->query( $query, $bind_variables, 0, "rowCount" );
$this->name = $return['name'];
$_SESSION['project'] = $return['path'];
$_SESSION['project_id'] = $return['id'];
echo formatJSEND( "success", array( "name" => $this->name, "path" => $this->path ) );
} else {
@ -360,102 +429,127 @@ class Project extends Common {
// Create
//////////////////////////////////////////////////////////////////
public function Create() {
public function Create( $path, $name, $public ) {
if ( $this->name != '' && $this->path != '' ) {
$return = array(
"status" => null,
"message" => null,
);
$this->path = $this->cleanPath();
$this->name = htmlspecialchars( $this->name );
if ( ! $this->isAbsPath( $this->path ) ) {
if( $public === true ) {
$this->path = $this->SanitizePath();
$owner = -1;
} else {
$owner = $_SESSION["user_id"];
}
if ( $this->path != '' ) {
if( ! $this->public_project && ! $this->isAbsPath( $this->path ) ) {
if ( $name != '' && $path != '' ) {
$user_path = WORKSPACE . '/' . preg_replace( '/[^\w-]/', '', strtolower( $_SESSION["user"] ) );
$path = $this->clean_path( $path );
$name = htmlspecialchars( $name );
if ( ! $this->isAbsPath( $path ) ) {
$path = $this->sanitize_path( $path );
}
if ( $path != '' ) {
$user_path = WORKSPACE . '/' . preg_replace( Filemanager::PATH_REGEX, '', strtolower( $_SESSION["user"] ) );
if( ! $this->isAbsPath( $path ) ) {
$path = $_SESSION["user"] . '/' . $path;
}
$pass = $this->check_duplicate( $path );
if ( $pass ) {
if( ! is_dir( $user_path ) ) {
mkdir( $user_path, 0755, true );
}
$this->path = $_SESSION["user"] . '/' . $this->path;
if ( ! $this->isAbsPath( $path ) ) {
if( ! is_dir( WORKSPACE . '/' . $path ) ) {
mkdir( WORKSPACE . '/' . $path, 0755, true );
}
$pass = $this->checkDuplicate();
if ( $pass ) {
if ( ! $this->isAbsPath( $this->path ) ) {
mkdir( WORKSPACE . '/' . $this->path );
} else {
if( ! is_admin() ) {
die( formatJSEND( "error", "Absolute Paths are only allowed for admins" ) );
}
if( is_admin() ) {
if ( defined( 'WHITEPATHS' ) ) {
$allowed = false;
foreach ( explode( ",", WHITEPATHS ) as $whitepath ) {
if ( strpos( $this->path, $whitepath ) === 0 ) {
if ( strpos( $path, $whitepath ) === 0 ) {
$allowed = true;
}
}
if ( ! $allowed ) {
die( formatJSEND( "error", "Absolute Path Only Allowed for " . WHITEPATHS ) );
$return["status"] = "error";
$return["message"] = "Absolute Path Only Allowed for " . WHITEPATHS;
}
}
if ( ! file_exists( $this->path ) ) {
if ( ! file_exists( $path ) ) {
if ( ! mkdir( $this->path . '/', 0755, true ) ) {
if ( ! mkdir( $path . '/', 0755, true ) ) {
die( formatJSEND( "error", "Unable to create Absolute Path" ) );
$return["status"] = "error";
$return["message"] = "Unable to create Absolute Path";
}
} else {
if ( ! is_writable( $this->path ) || ! is_readable( $this->path ) ) {
if ( ! is_writable( $path ) || ! is_readable( $path ) ) {
die( formatJSEND( "error", "No Read/Write Permission" ) );
$return["status"] = "error";
$return["message"] = "No Read/Write Permission";
}
}
}
$this->projects[] = array( "name" => $this->name, "path" => $this->path );
$this->add_project( $this->name, $this->path );
// Pull from Git Repo?
if ( $this->gitrepo && filter_var( $this->gitrepo, FILTER_VALIDATE_URL ) !== false ) {
$this->gitbranch = $this->SanitizeGitBranch();
if ( ! $this->isAbsPath( $this->path ) ) {
$this->command_exec = "cd " . escapeshellarg( WORKSPACE . '/' . $this->path ) . " && git init && git remote add origin " . escapeshellarg( $this->gitrepo ) . " && git pull origin " . escapeshellarg( $this->gitbranch );
} else {
$this->command_exec = "cd " . escapeshellarg( $this->path ) . " && git init && git remote add origin " . escapeshellarg( $this->gitrepo ) . " && git pull origin " . escapeshellarg( $this->gitbranch );
}
$this->ExecuteCMD();
}
echo formatJSEND( "success", array( "name" => $this->name, "path" => $this->path ) );
} else {
echo formatJSEND( "error", "A Project With the Same Name or Path Exists" );
}
} else {
echo formatJSEND( "error", "Project Name/Folder not allowed" );
$return["status"] = "error";
$return["message"] = "Absolute Paths are only allowed for admins";
}
}
if( $return["status"] == null ) {
$this->projects[] = array( "name" => $name, "path" => $path );
$result = $this->add_project( $name, $path, $owner );
if( $result > 0 ) {
$return["status"] = "success";
$return["message"] = "Created Project";
$return["data"] = array( "name" => $name, "path" => $path );
} else {
$return["status"] = "error";
$return["message"] = "A Project With the Same Name or Path Exists";
}
}
} else {
echo formatJSEND( "error", "Project Name/Folder is empty" );
$return["status"] = "error";
$return["message"] = "A Project With the Same Name or Path Exists";
}
} else {
$return["status"] = "error";
$return["message"] = "Project Name/Folder not allowed";
}
} else {
$return["status"] = "error";
$return["message"] = "Project Name/Folder is empty";
}
return $return;
}
//////////////////////////////////////////////////////////////////
@ -495,35 +589,24 @@ class Project extends Common {
public function Delete() {
if( Permissions::has_owner( $this->path ) ) {
global $sql;
$query = "DELETE FROM projects WHERE path=? AND ( owner=? OR owner='nobody' );";
$bind_variables = array( $this->path, $_SESSION["user"] );
$query = "DELETE FROM projects WHERE path=?";
$bind_variables = array( $this->path );
$return = $sql->query( $query, $bind_variables, 0, "rowCount" );
if( $return > 0 ) {
echo( formatJSEND( "success", "Successfully deleted $project_name" ) );
exit( formatJSEND( "success", "Successfully deleted project." ) );
} else {
echo formatJSEND( "error", "Error deleting project $project_name" );
exit( formatJSEND( "error", "Error deleting project" ) );
}
} else {
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;
}
//////////////////////////////////////////////////////////////////
@ -533,7 +616,13 @@ class Project extends Common {
public function SanitizePath() {
$sanitized = str_replace( " ", "_", $this->path );
return preg_replace( '/[^\w-]/', '', strtolower( $sanitized ) );
return preg_replace( Filemanager::PATH_REGEX, '', strtolower( $sanitized ) );
}
public function sanitize_path( $path ) {
$sanitized = str_replace( " ", "_", $path );
return preg_replace( Filemanager::PATH_REGEX, '', strtolower( $sanitized ) );
}
//////////////////////////////////////////////////////////////////
@ -554,31 +643,16 @@ class Project extends Common {
return $path;
}
//////////////////////////////////////////////////////////////////
// Execute Command
//////////////////////////////////////////////////////////////////
public function clean_path( $path ) {
public function ExecuteCMD() {
// prevent Poison Null Byte injections
$path = str_replace( chr( 0 ), '', $path );
if ( function_exists( 'system' ) ) {
// prevent go out of the workspace
while( strpos( $path, '../' ) !== false ) {
ob_start();
system( $this->command_exec );
ob_end_clean();
} elseif( function_exists( 'passthru' ) ) {
//passthru
ob_start();
passthru($this->command_exec);
ob_end_clean();
} elseif ( function_exists( 'exec' ) ) {
//exec
exec( $this->command_exec, $this->output );
} elseif ( function_exists( 'shell_exec' ) ) {
//shell_exec
shell_exec( $this->command_exec );
}
$path = str_replace( '../', '', $path );
}
return $path;
}
}

View file

@ -32,30 +32,36 @@ if( $_GET['action'] == 'add_user' ) {
"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 ) ) ) {
$Project->user = $_GET['username'];
exit( formatJSEND( "error", "No access set." ) );
} else {
echo formatJSEND( "error", "No username set." );
return;
$access = Permissions::LEVELS[$_GET['access']];
}
if( $_GET['project_path'] != '' ) {
if( isset( $_GET['user_id'] ) && ! in_array( $_GET['user_id'], $invalid_users ) ) {
$Project->path = $_GET['project_path'];
$user = $_GET['user_id'];
} else {
echo formatJSEND( "error", "No project path set." );
return;
exit( formatJSEND( "error", "No user id set." ) );
}
if( $Project->check_owner( $_GET["project_path"], true ) ) {
if( isset( $_GET['project_path'] ) && $_GET['project_path'] != '' ) {
$Project->add_user();
$project = $_GET['project_path'];
} else {
echo formatJSEND( "error", "You can not manage this project." );
exit( formatJSEND( "error", "No project path set." ) );
}
if( $Project->check_owner( $_GET['project_path'], true ) ) {
exit( json_encode( $Project->add_user( $project, $user, $access ) ) );
} else {
exit( formatJSEND( "error", "You can not manage this project." ) );
}
}
@ -66,27 +72,11 @@ if( $_GET['action'] == 'add_user' ) {
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();
$name = $_GET['project_name'];
$public = ( $_GET['public_project'] != 'true' ) ? false : true;
$path = ( $_GET['project_path'] != '' ) ? $_GET['project_path'] : $_GET['project_name'];
$return = $Project->Create( $path, $name, $public );
exit( json_encode( $return ) );
}
//////////////////////////////////////////////////////////////////
@ -110,7 +100,7 @@ if( $_GET['action'] == 'current' ) {
if( $_GET['action'] == 'delete' ) {
if( checkPath( $_GET['project_path'] ) ) {
if( isset( $_GET['project_path'] ) ) {
$Project->path = $_GET['project_path'];
$Project->Delete();
@ -123,8 +113,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 );
}
@ -147,7 +136,15 @@ if( $_GET['action'] == 'get_current' ) {
$Project->no_return = true;
}
$Project->GetFirst();
$project = $Project->GetFirst();
if( $project == null ) {
exit( formatJSEND( "error", "Error, Could not load a projet." ) );
} else {
exit( formatJSEND( "success", $project ) );
}
} else {
// Load current
@ -155,7 +152,7 @@ if( $_GET['action'] == 'get_current' ) {
$project_name = $Project->GetName();
if( ! $no_return ) {
echo formatJSEND( "success", array( "name" => $project_name, "path" => $_SESSION['project'] ) );
exit( formatJSEND( "success", array( "name" => $project_name, "path" => $_SESSION['project'] ) ) );
}
}
}
@ -184,7 +181,7 @@ if( $_GET['action'] == 'get_owner' ) {
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'] ) );
}
@ -200,30 +197,36 @@ if( $_GET['action'] == 'remove_user' ) {
"undefined"
);
if( ! in_array( $_GET['username'], $invalid ) ) {
$Project->user = $_GET['username'];
} else {
echo formatJSEND( "error", "No username set." );
return;
}
if( ! in_array( $_GET['project_path'], $invalid ) ) {
if( isset( $_GET["project_path"] ) && ! in_array( $_GET['project_path'], $invalid ) ) {
$Project->path = $_GET['project_path'];
} else {
echo formatJSEND( "error", "No project path set." );
return;
exit( formatJSEND( "error", "No project path set." ) );
}
if( isset( $_GET["project_id"] ) && ! in_array( $_GET['project_id'], $invalid ) ) {
$Project->project_id = $_GET['project_id'];
} else {
exit( formatJSEND( "error", "No project id set." ) );
}
if( isset( $_GET["user_id"] ) && ! in_array( $_GET['user_id'], $invalid ) ) {
$user_id = $_GET["user_id"];
} else {
exit( formatJSEND( "error", "No user id set." ) );
}
if( $Project->check_owner( $_GET["project_path"], true ) ) {
$Project->remove_user();
$Project->remove_user( $user_id );
} else {
echo formatJSEND( "error", "You can not manage this project." );
exit( formatJSEND( "error", "You can not manage this project." ) );
}
}
@ -233,7 +236,7 @@ if( $_GET['action'] == 'remove_user' ) {
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" ) );
}

View file

@ -9,6 +9,7 @@
require_once( '../../common.php' );
require_once( './class.project.php' );
require_once( '../user/class.user.php' );
//////////////////////////////////////////////////////////////////
// Verify Session or Key
@ -56,7 +57,12 @@ switch( $_GET['action'] ) {
case 'list':
//Get projects data
if( isset( $_GET["all"] ) ) {
$projects = $Project->get_all_projects();
} else {
$projects = $Project->get_projects();
}
?>
<label><?php i18n("Project List"); ?></label>
<div id="project-list">
@ -72,6 +78,8 @@ switch( $_GET['action'] ) {
<div class="project-wrapper">
<table width="100%" style="word-wrap: break-word;word-break: break-all;">
<?php
if( is_array( $projects ) ) {
foreach( $projects as $project => $data ) {
$show = true;
@ -84,12 +92,12 @@ switch( $_GET['action'] ) {
<td width="250"><?php echo($data['path']);?></td>
<?php
$owner = $Project->get_owner( $data['path'] );
if( $owner == 'nobody' ) {
if( $owner == -1 ) {
?>
<td width="70"><a onclick="codiad.message.error(i18n('Public projects can not be managed'));" class="icon-block bigger-icon"></a></td>
<?php
} elseif( $owner !== $_SESSION["user"] ) {
} elseif( $owner !== $_SESSION["user_id"] ) {
?>
<td width="70"><a onclick="codiad.message.error(i18n('Projects owned by others can not be managed'));" class="icon-block bigger-icon"></a></td>
@ -107,7 +115,7 @@ switch( $_GET['action'] ) {
?>
<td width="70"><a onclick="codiad.message.error(i18n('Active Project Cannot Be Removed'));" class="icon-block bigger-icon"></a></td>
<?php
} elseif( $owner !== $_SESSION["user"] ) {
} elseif( $owner !== $_SESSION["user_id"] && $owner != -1 ) {
?>
<td width="70"><a onclick="codiad.message.error(i18n('Projects owned by others can not be deleted'));" class="icon-block bigger-icon"></a></td>
@ -123,6 +131,11 @@ switch( $_GET['action'] ) {
<?php
}
}
} else {
$error = json_decode( $projects, true );
echo $error["message"];
}
?>
</table>
</div>
@ -196,34 +209,55 @@ switch( $_GET['action'] ) {
*/
if( ! isset( $_GET["path"] ) || ! $Project->check_owner( $_GET["path"], true ) ) {
?>
<pre>Error, you either do not own this project or it is a public project.</pre>
<p>Error, you either do not own this project or it is a public project.</p>
<button class="btn-right" onclick="codiad.project.list();return false;"><?php i18n( "Back" );?></button>
<?php
return;
}
// Get projects data
$User = new User();
$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 );
$user = $User->get_user( $_SESSION["user"] );
if( isset( $users["status"] ) && $users["status"] == "error" ) {
?>
<form>
<input type="hidden" name="project_path" value="<?php echo( $path );?>">
<p>Error, could not fetch users information.</p>
<button class="btn-left" onclick="codiad.project.list();return false;"><?php i18n( "Back" );?></button>
<?php
exit();
} else if( empty( $users ) ) {
?>
<p>Error, You must have more than one user registered in your Codiad instance to manage permissions.</p>
<button class="btn-left" onclick="codiad.project.list();return false;"><?php i18n( "Back" );?></button>
<?php
exit();
}
?>
<form onSubmit="event.preventDefault();">
<input type="hidden" name="project_path" value="<?php echo $path;?>">
<input type="hidden" name="project_id" value="<?php echo $project["id"];?>">
<label><span class="icon-pencil"></span><?php i18n( "Add Users" );?></label>
<input id="search_users" type="text" onkeyup="codiad.project.search_users();" />
<select id="user_list" name="user_list">
<?php
foreach( $users as $user ) {
foreach( $users as $i ) {
?>
<option value="<?php echo htmlentities( $user );?>"><?php echo htmlentities( $user );?></option>
<option value="<?php echo htmlentities( $i["id"] );?>"><?php echo htmlentities( $i["username"] );?></option>
<?php
}
?>
</select>
<button class="btn-left" onclick="codiad.project.add_user();">Add User</button>
<?php
if( $access == null ) {
if( $access == null || empty( $access ) ) {
?>
<p>No users have been given access.</p>
@ -233,15 +267,47 @@ switch( $_GET['action'] ) {
?>
<table id="access_list">
<?php
foreach( $access as $user ) {
foreach( $access as $row => $user_permissions ) {
$i = null;
foreach( $users as $r => $current_user ) {
if( $current_user["id"] == $user_permissions["user"] ) {
$i = $current_user;
break;
}
}
if( ! $i ) {
continue;
}
?>
<tr>
<td>
<p><?php echo htmlentities( $user );?></p>
<p><?php echo htmlentities( $i["username"] );?></p>
</td>
<td>
<button class="btn-left" onclick="codiad.project.remove_user( '<?php echo htmlentities( $user );?>' );">Remove Access</button>
<select onchange="codiad.project.change_access( event, <?php echo $i["id"];?> );">
<?php
foreach( Permissions::LEVELS as $level => $id ) {
if( $id == $user_permissions["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( $i["id"] );?>' );">Remove Access</button>
</td>
</tr>
<?php
@ -251,6 +317,7 @@ switch( $_GET['action'] ) {
<?php
}
?>
<button class="btn-left" onclick="codiad.project.list();return false;"><?php i18n( "Back" );?></button>
<button class="btn-right" onclick="codiad.modal.unload();return false;"><?php i18n( "Done" );?></button>
<form>
<?php

View file

@ -53,15 +53,12 @@
add_user: function() {
var _this = this;
let _this = this;
let id = $( '#modal-content form select[name="user_list"]' ).val();
let project_path = $( '#modal-content form input[name="project_path"]' ).val();
let project_id = $( '#modal-content form input[name="project_id"]' ).val();
$( '#modal-content form' ).live( 'submit', function( e ) {
e.preventDefault();
username = $( '#modal-content form select[name="user_list"]' ).val();
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 ) + '&project_id=' + encodeURIComponent( project_id ) + '&user_id=' + encodeURIComponent( id ) + '&access=delete', function( data ) {
response = codiad.jsend.parse( data );
console.log( response );
@ -70,9 +67,27 @@
codiad.project.manage_access( project_path );
}
});
});
},
change_access: function( e, id ) {
let _this = codiad.project;
let project_path = $( '#modal-content form input[name="project_path"]' ).val();
let project_id = $( '#modal-content form input[name="project_id"]' ).val();
let access = $( e.target ).children( "option:selected" ).val();
console.log( access, id, project_path, project_id );
$.get( _this.controller + '?action=add_user&project_path=' + encodeURIComponent( project_path ) + '&id=' + encodeURIComponent( project_id ) + '&user_id=' + encodeURIComponent( id ) + '&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
@ -233,6 +248,12 @@
codiad.modal.load( 500, this.dialog + '?action=list' );
},
list_all: function() {
$( '#modal-content form' ).die( 'submit' ); // Prevent form bubbling
codiad.modal.load( 500, this.dialog + '?action=list&all=true' );
},
/**
* Turn the access array into a table.
*/
@ -308,6 +329,7 @@
codiad.finder.contractFinder();
$.get( this.controller + '?action=open&path=' + encodeURIComponent( path ), function( data ) {
console.log( data );
var projectInfo = codiad.jsend.parse(data);
if ( projectInfo != 'error' ) {
@ -353,12 +375,10 @@
var _this = this;
$( '#modal-content form' ).live( 'submit', function( e ) {
let project_path = $( '#modal-content form input[name="project_path"]' ).val();
let project_id = $( '#modal-content form input[name="project_id"]' ).val();
e.preventDefault();
project_path = $( '#modal-content form input[name="project_path"]' ).val()
$.get( _this.controller + '?action=remove_user&project_path=' + encodeURIComponent( project_path ) + '&username=' + encodeURIComponent( user ), function( data ) {
$.get( _this.controller + '?action=remove_user&project_path=' + encodeURIComponent( project_path ) + '&project_id=' + encodeURIComponent( project_id ) + '&user_id=' + encodeURIComponent( user ), function( data ) {
response = codiad.jsend.parse( data );
console.log( response );
@ -367,7 +387,6 @@
codiad.project.manage_access( project_path );
}
});
});
},
//////////////////////////////////////////////////////////////////

View file

@ -113,7 +113,10 @@ class Settings {
$result = $sql->query( $query, $bind_variables, 0, "rowCount" );
} else {
$query = "DELETE FROM options WHERE name=? AND username=?";
$query = array(
"*" => "DELETE FROM options WHERE name=? AND user=?",
"pgsql" => 'DELETE FROM options WHERE name=? AND "user"=?',
);
$bind_variables = array(
$option,
$this->username,
@ -138,17 +141,20 @@ class Settings {
$query = "SELECT value FROM options WHERE name=?;";
$bind_variables = array( $option );
$return = $sql->query( $query, $bind_variables, array() )[0];
$return = $sql->query( $query, $bind_variables, array() );
} else {
$query = "SELECT value FROM user_options WHERE name=? AND username=?;";
$bind_variables = array( $option, $this->username );
$return = $sql->query( $query, $bind_variables, array() )[0];
$query = array(
"*" => "SELECT value FROM user_options WHERE name=? AND user=?;",
"pgsql" => 'SELECT value FROM user_options WHERE name=? AND "user"=?;',
);
$bind_variables = array( $option, $_SESSION["user_id"] );
$return = $sql->query( $query, $bind_variables, array() );
}
if( ! empty( $return ) ) {
$return = $return["value"];
$return = $return[0]["value"];
} else {
$return = null;
@ -172,8 +178,11 @@ class Settings {
global $sql;
$query = "SELECT name, value FROM user_options WHERE username=?;";
$bind_variables = array( $this->username );
$query = array(
"*" => "SELECT name, value FROM user_options WHERE user=?;",
"pgsql" => 'SELECT name, value FROM user_options WHERE "user"=?;',
);
$bind_variables = array( $_SESSION["user_id"] );
$return = $sql->query( $query, $bind_variables, array() );
$options = array();
@ -220,7 +229,10 @@ class Settings {
public function Load() {
global $sql;
$query = "SELECT DISTINCT * FROM user_options WHERE username=?;";
$query = array(
"*" => "SELECT DISTINCT * FROM user_options WHERE user=?;",
"pgsql" => 'SELECT DISTINCT * FROM user_options WHERE "user"=?;',
);
$bind_variables = array(
$this->username
);
@ -241,7 +253,7 @@ class Settings {
global $sql;
if( $user_setting == null ) {
$query = "INSERT INTO options ( name, username, value ) VALUES ( ?, ? );";
$query = "INSERT INTO options ( name, value ) VALUES ( ?, ? );";
$bind_variables = array(
$option,
$value,
@ -259,21 +271,27 @@ class Settings {
}
} else {
$query = "INSERT INTO user_options ( name, username, value ) VALUES ( ?, ?, ? );";
$query = array(
"*" => "UPDATE user_options SET value=? WHERE name=? AND user=?;",
"pgsql" => 'UPDATE user_options SET value=? WHERE name=? AND "user"=?;',
);
$bind_variables = array(
$option,
$this->username,
$value,
$option,
$_SESSION["user_id"],
);
$result = $sql->query( $query, $bind_variables, 0, "rowCount" );
if( $result == 0 ) {
$query = "UPDATE user_options SET value=? WHERE name=? AND username=?;";
$query = array(
"*" => "INSERT INTO user_options ( name, user, value ) VALUES ( ?, ?, ? );",
"pgsql" => 'INSERT INTO user_options ( name, "user", value ) VALUES ( ?, ?, ? );',
);
$bind_variables = array(
$value,
$option,
$this->username,
$_SESSION["user_id"],
$value,
);
$result = $sql->query( $query, $bind_variables, 0, "rowCount" );
}

View file

@ -44,8 +44,8 @@ require_once('../../common.php');
<td><?php i18n("Live Autocomplete"); ?></td>
<td>
<select class="setting" data-setting="codiad.editor.autocomplete">
<option value="false" selected><?php i18n("Off");?></option>
<option value="true"><?php i18n("On"); ?></option>
<option value="false" selected><?php i18n("Off");?></option>
</select>
</td>
</tr>
@ -53,8 +53,8 @@ require_once('../../common.php');
<td><?php i18n("Over Scroll"); ?></td>
<td>
<select class="setting" data-setting="codiad.editor.overScroll">
<option value="0" selected><?php i18n("None");?></option>
<option value="0.5"><?php i18n("Half");?></option>
<option value="0"><?php i18n("None");?></option>
<option value="0.5" selected><?php i18n("Half");?></option>
<option value="1"><?php i18n("Full");?></option>
</select>
</td>

View file

@ -1,458 +0,0 @@
<?php
class sql_conversions {
public $actions = array(
"create" => array(
"mysql" => "CREATE TABLE IF NOT EXISTS",
"pgsql" => "CREATE TABLE IF NOT EXISTS",
"sqlite" => "CREATE TABLE IF NOT EXISTS",
),
"delete" => array(
"mysql" => "DELETE",
"pgsql" => "DELETE",
"sqlite" => "DELETE",
),
"find" => array(
"mysql" => "LOCATE( %substring%, %string% )",
"pgsql" => "POSITION( %substring% in %string% )",
"sqlite" => "INSTR( %string%, %substring% )",
),
"select" => array(
"mysql" => "SELECT",
"pgsql" => "SELECT",
"sqlite" => "SELECT",
),
"update" => array(
"mysql" => "UPDATE",
"pgsql" => "UPDATE",
"sqlite" => "UPDATE",
),
);
public $comparisons = array(
"equal" => array(
"mysql" => "=",
"pgsql" => "=",
"sqlite" => "=",
),
"less than" => array(
"mysql" => "<",
"pgsql" => "<",
"sqlite" => "<",
),
"more than" => array(
"mysql" => ">",
"pgsql" => ">",
"sqlite" => ">",
),
"not" => array(
"mysql" => "!",
"pgsql" => "!",
"sqlite" => "!",
),
"not equal" => array(
"mysql" => "!=",
"pgsql" => "!=",
"sqlite" => "!=",
),
"where" => array(
"mysql" => "WHERE",
"pgsql" => "WHERE",
"sqlite" => "WHERE",
),
);
public $data_types = array(
"bool" => array(
"mysql" => "BOOL",
"pgsql" => "BOOL",
"sqlite" => "BOOL",
),
"int" => array(
"mysql" => "INT",
"pgsql" => "INT",
"sqlite" => "INT",
),
"string" => array(
"mysql" => "VARCHAR(255)",
"pgsql" => "VARCHAR",
"sqlite" => "VARCHAR",
),
"text" => array(
"mysql" => "TEXT",
"pgsql" => "TEXT",
"sqlite" => "TEXT",
),
);
public $general = array(
"from" => array(
"mysql" => "FROM",
"pgsql" => "FROM",
"sqlite" => "FROM",
),
);
public $specials = array(
"id" => array(
"mysql" => "NOT NULL AUTO_INCREMENT PRIMARY KEY",
"pgsql" => "SERIAL PRIMARY KEY",
"sqlite" => "SERIAL PRIMARY KEY",
),
"key" => array(
"mysql" => "KEY",
"pgsql" => "KEY",
"sqlite" => "KEY",
),
"auto increment" => array(
"mysql" => "AUTO_INCREMENT",
"pgsql" => "AUTO_INCREMENT",
"sqlite" => "AUTO_INCREMENT",
),
"not null" => array(
"mysql" => "NOT NULL",
"pgsql" => "NOT NULL",
"sqlite" => "NOT NULL",
),
"null" => array(
"mysql" => "NULL",
"pgsql" => "NULL",
"sqlite" => "NULL",
),
"unique" => array(
"mysql" => "CONSTRAINT %constraint_name% UNIQUE ( %field_names% )",
"pgsql" => "CONSTRAINT %constraint_name% UNIQUE ( %field_names% )",
"sqlite" => "CONSTRAINT %constraint_name% UNIQUE ( %field_names% )",
),
);
public $wraps = array(
"close" => array(
"mysql" => "`",
"mssql" => "]",
"pgsql" => "\"",
"sqlite" => "\"",
),
"open" => array(
"mysql" => "`",
"mssql" => "[",
"pgsql" => "\"",
"sqlite" => "\"",
),
);
public function check_field( $needle, $haystack ) {
$field = preg_replace_callback(
// Matches parts to be replaced: '[field]'
'/(\[.*?\])/',
// Callback function. Use 'use()' or define arrays as 'global'
function( $matches ) use ( $haystack ) {
// Remove square brackets from the match
// then use it as variable name
$match = trim( $matches[1], "[]" );
return $match;
},
// Input string to search in.
$needle
);
if( $field === $needle ) {
$field = false;
}
return $field;
}
public function find( $substring, $string ) {
$dbtype = DBTYPE;
$find_string = $this->actions["find"][$dbtype];
$find_string = str_replace( "%string%", $string, $find_string );
$find_string = str_replace( "%substring%", $substring, $find_string );
return $find_string;
}
public function select( $table, $fields, $where ) {
$dbtype = DBTYPE;
$id_close = $this->wraps["close"][$dbtype];
$id_open = $this->wraps["open"][$dbtype];
$query = $this->actions["select"][$dbtype] . " ";
$bind_vars = array();
if( empty( $fields ) ) {
$query .= " * ";
}
foreach( $fields as $field ) {
$query .= $field . ",";
}
$query = substr( $query, 0, -1 );
$query .= " {$this->general["from"][$dbtype]} {$table} ";
if( ! empty( $where ) ) {
$query .= " {$this->comparisons["where"][$dbtype]} ";
}
foreach( $where as $comparison ) {
$comparison_string = "";
//Put a replace of %% symbols with fields and open / close
if( $comparison[0] == "find" ) {
$c1 = $this->check_field( $comparison[1], $fields );
$c2 = $this->check_field( $comparison[2], $fields );
$c3 = $this->check_field( $comparison[3][1], $fields );
if( ! $c1 === FALSE ) {
$c1 = $id_open . $c1 . $id_close;
} else {
$c1 = "?";
array_push( $bind_vars, $comparison[1] );
}
if( ! $c2 === FALSE ) {
$c2 = $id_open . $c2 . $id_close;
} else {
$c2 = "?";
array_push( $bind_vars, $comparison[2] );
}
if( ! $c3 === FALSE ) {
$c3 = $id_open . $c3 . $id_close;
} else {
$c3 = "?";
array_push( $bind_vars, $comparison[3][1] );
}
$c0 = $this->find( $c1, $c2 );
$comparison_string .= "{$c0} {$this->comparisons[$comparison[3][0]][$dbtype]} {$c3}";
} elseif( $comparison[0] == "in" ) {
} elseif( $comparison[0] == "limit" ) {
} else {
if( in_array( $fields, $comparison[1] ) ) {
$comparison[1] = $id_open . $comparison[1] . $id_close;
}
if( in_array( $fields, $comparison[3] ) ) {
$comparison[3] = $id_open . $comparison[3] . $id_close;
}
$comparison_string .= "{$comparison[1]} {$this->$comparisons[$comparison[0]][$dbtype]} {$comparison[2]}";
}
$index = array_search( $comparison, $where );
if( $index ) {
} else {
$query .= "{$comparison_string} ";
}
}
//$query = substr( $query, 0, -1 );
$query .= ";";
return array( $query, $bind_vars );
}
public function table( $table_name, $fields, $attributes ) {
$dbtype = DBTYPE;
$id_close = $this->wraps["close"][$dbtype];
$id_open = $this->wraps["open"][$dbtype];
$query = "{$this->actions["create"][$dbtype]} {$table_name} (";
foreach( $fields as $id => $type ) {
$query .= "{$id} {$this->data_types[$type][$dbtype]}";
if( isset( $attributes[$id] ) ) {
foreach( $attributes[$id] as $attribute ) {
$attribute_string = $this->specials["$attribute"][$dbtype];
if( $attribute == "unique" ) {
continue;
}
if( $dbtype == "pgsql" ) {
if( $id == "id" ) {
$query = substr( $query, 0, -( strlen( " {$this->data_types[$type][$dbtype]}" ) ) );
}
}
if( ! strpos( $attribute_string, "%table_name%" ) === FALSE ) {
$attribute_string = str_replace( "%table_name%", $table_name, $attribute_string );
}
if( ! strpos( $attribute_string, "%fields%" ) === FALSE ) {
$fields_string = "";
foreach( $fields as $field ) {
$fields_string .= "{$id_open}field{$id_close},";
}
$fields_string = substr( $fields_string, 0, -1 );
$attribute_string = str_replace( "%fields%", $fields_string, $attribute_string );
}
$query .= " {$attribute_string}";
}
}
$query .= ",";
}
$id_close = $this->wraps["close"][$dbtype];
$id_open = $this->wraps["open"][$dbtype];
$fields_string = "";
$unique_string = "";
$unique_length = 0;
foreach( $attributes as $id => $attribute ) {
if( in_array( "unique", $attribute ) ) {
$unique_length++;
}
}
foreach( $attributes as $id => $attribute ) {
if( is_array( $attribute ) && in_array( "unique", $attribute ) ) {
if( $unique_string == "" ) {
$unique_string = $this->specials["unique"][$dbtype] . ",";
}
if( $dbtype == "mysql" && $fields ) {
if( $fields[$id] == "text" ) {
$field_length = ( 3000 / $unique_length );
$fields_string .= "{$id_open}{$id}{$id_close}($field_length),";
} elseif( $fields[$id] == "string" ) {
$field_length = ( 3000 / $unique_length );
$fields_string .= "{$id_open}{$id}{$id_close}(255),";
}
} else {
$fields_string .= "{$id_open}{$id}{$id_close},";
}
}
}
$unique_string = str_replace( "%constraint_name%", strtolower( preg_replace( '#[^A-Za-z0-9' . preg_quote( '-_@. ').']#', '', $fields_string ) ), $unique_string );
$unique_string = str_replace( "%field_names%", substr( $fields_string, 0, -1 ), $unique_string );
$query .= $unique_string;
$query = substr( $query, 0, -1 );
$query .= ")";
if( $dbtype == "mysql" ) {
$query .= " ENGINE=InnoDB;";
} else {
$query .= ";";
}
return( $query );
}
public function tables( $tables ) {
$query = "";
foreach( $tables as $table_name => $table_data ) {
$query .= $this->table( $table_name, $table_data["fields"], $table_data["attributes"] ) . PHP_EOL;
}
return( $query );
}
public function update( $table, $fields, $where ) {
}
}
?>

View file

@ -1,6 +1,6 @@
<?php
require_once( __DIR__ . "/class.sql.conversions.php" );
require_once( __DIR__ . "/../permissions/class.permissions.php" );
class sql {
@ -12,13 +12,10 @@ class sql {
);
public $connection = null;
public $conversions = null;
public $identifier_character = null;
protected static $instance = null;
public function __construct() {
$this->conversions = new sql_conversions();
}
public function close() {
@ -35,152 +32,45 @@ class sql {
$dbtype = DBTYPE;
$username = DBUSER;
$password = DBPASS;
$options = array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
);
$this->connection = new PDO( "{$dbtype}:host={$host};dbname={$dbname}", $username, $password );
$this->connection = new PDO( "{$dbtype}:host={$host};dbname={$dbname}", $username, $password, $options );
}
return( $this->connection );
}
public function create_table( $table_name, $fields=array(), $attributes=array() ) {
$query = $this->conversions->table( $table_name, $fields, $attributes );
//$this->query( $query, array(), array(), null, "rowCount" );
}
public function create_default_tables() {
$result = $this->create_tables(
array(
"active" => array(
"fields" => array(
"username" => "string",
"path" => "text",
"position" => "string",
"focused" => "string"
),
"attributes" => array(
"username" => array( "not null", "unique" ),
"path" => array( "not null", "unique" ),
"focused" => array( "not null" ),
)
),
"options" => array(
"fields" => array(
"id" => "int",
"name" => "string",
"value" => "text",
),
"attributes" => array(
"id" => array( "id" ),
"name" => array( "not null", "unique" ),
"value" => array( "not null" ),
)
),
"projects" => array(
"fields" => array(
"id" => "int",
"name" => "string",
"path" => "text",
"owner" => "string",
"access" => "string",
),
"attributes" => array(
"id" => array( "id" ),
"name" => array( "not null" ),
"path" => array( "not null", "unique" ),
"owner" => array( "not null", "unique" ),
"access" => array(),
)
),
"users" => array(
"fields" => array(
"id" => "int",
"first_name" => "string",
"last_name" => "string",
"username" => "string",
"password" => "text",
"email" => "string",
"project" => "string",
"access" => "string",
"groups" => "string",
"token" => "string",
),
"attributes" => array(
"id" => array( "id" ),
"username" => array( "not null", "unique" ),
"password" => array( "not null" ),
"access" => array( "not null" ),
)
),
"user_options" => array(
"fields" => array(
"id" => "int",
"name" => "string",
"username" => "string",
"value" => "text",
),
"attributes" => array(
"id" => array( "id" ),
"name" => array( "not null", "unique" ),
"username" => array( "not null", "unique" ),
"value" => array( "not null" ),
)
),
)
$create_tables = $this->create_tables();
$structure_updates = $this->update_table_structure();
$result = array(
"create_tables" => $create_tables,
"structure_updates" => $structure_updates
);
return $result;
}
public function create_tables( $table ) {
public function create_tables() {
/**
Tables layout
array(
$script = __DIR__ . "/scripts/" . DBTYPE . ".sql";
"table_name" => array(
if( ! is_file( $script ) ) {
"fields" => array(
return "Error, no database scripts specified for currently selected dbtype.";
}
"id" => "int",
"test_field" => "string"
),
"attributes" => array(
try {
"id" => array( "id" ),
"test_field" => array( "not null" ),
)
),
"table2_name" => array(
"fields" => array(
"id" => "int",
"test_field" => "string"
),
"attributes" => array(
"id" => array( "id" ),
"test_field" => array( "not null" ),
)
)
);
*/
$query = $this->conversions->tables( $table );
$query = file_get_contents( $script );
$connection = $this->connect();
$result = $connection->exec( $query );
$error = $connection->errorInfo();
//echo var_dump( $query, $result, $connection->errorInfo() ) . "<br>";
if ( $result === false || ! $error[0] == "00000" ) {
return $error;
} else {
return true;
} catch( exception $error ) {
return $error->getMessage();
}
}
@ -213,23 +103,397 @@ class sql {
return self::$instance;
}
public function select( $table, $fields=array(), $where=array() ) {
public function update_table_structure() {
$array = $this->conversions->select( $table, $fields, $where );
$query = $array[0];
$bind_vars = $array[1];
$result = $this->query( $query, $bind_vars, array() );
//echo var_dump( $query, $bind_vars ) . "<br>";
return $result;
$status_updates = array();
$connection = $this->connect();
if( DBTYPE === "mysql" || DBTYPE === "pgsql" ) {
try {
$access_query = array(
"mysql" => "INSERT INTO access( project, user, level ) VALUES ",
"pgsql" => '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;
}
public function update( $table, $fields=array(), $where=array() ) {
foreach( $access as $granted_user ) {
$query = $this->conversions->update( $table, $fields, $where );
//echo var_dump( $query ) . "<br>";
if( $granted_user == $user["username"] ) {
$access_query[DBTYPE] .= "( {$project["id"]}, {$user["id"]}, $delete ),";
}
}
}
}
public function query( $query, $bind_variables, $default, $action='fetchAll', $show_errors=false ) {
if( $access_query !== "INSERT INTO access( project, user, level ) VALUES " ) {
$result = $this->query( substr( $access_query[DBTYPE], 0, -1 ), array(), 0, "rowCount", "exception" );
}
$result = $this->query( "ALTER TABLE projects DROP COLUMN access", array(), 0, "rowCount" );
$status_updates["access_column"] = "Cached data and removed access column.";
} catch( Exception $error ) {
//The access field is not there.
//echo var_export( $error->getMessage(), $access_query );
$status_updates["access_column"] = array(
"error_message" => $error->getMessage(),
"dev_message" => "No access column to convert."
);
}
try {
$update_query = "";
$projects = $this->query( "SELECT id, path FROM projects", array(), array(), "fetchAll", "exception" );
$users = $this->query( "SELECT username,project FROM users", array(), array(), "fetchAll", "exception" );
$convert = false;
$delete = Permissions::LEVELS["delete"];
foreach( $users as $row => $user ) {
if( ! is_numeric( $user["project"] ) ) {
$convert = true;
}
}
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 INT", array(), array(), "rowCount", "exception" );
foreach( $users as $row => $user ) {
foreach( $projects as $row => $project ) {
if( $project["path"] == $user["project"] ) {
$result = $this->query( "UPDATE users SET project=? WHERE username = ?;", array( $project["id"], $user["username"] ), array(), "rowCount", "exception" );
break;
}
}
}
} else {
$status_updates["users_current_project"] = array( "dev_message" => "Users current project column to project_id conversion not needed." );
}
} catch( Exception $error ) {
//echo var_dump( $error->getMessage() );
$status_updates["users_current_project"] = array(
"error_message" => $error->getMessage(),
"dev_message" => "Users current project column to project_id conversion failed."
);
}
try {
$this->query( array(
"mysql" => "ALTER TABLE user_options DROP INDEX name255username255;",
"pgsql" => "ALTER TABLE user_options DROP CONSTRAINT name255username255;",
), array(), 0, "rowCount", "exception" );
} catch( Exception $error ) {
//The access field is not there.
//echo var_export( $error->getMessage(), $access_query );
$status_updates["nameusername_user_option_constraint"] = array(
"error_message" => $error->getMessage(),
"dev_message" => "No constriant to remove."
);
}
try {
$update_query = array(
"mysql" => "",
"pgsql" => "",
);
$options = $this->query( "SELECT id, name, username, value FROM user_options", array(), array(), "fetchAll", "exception" );
$users = $this->query( "SELECT id, username FROM users", array(), array(), "fetchAll", "exception" );
$delete = Permissions::LEVELS["delete"];
$convert = false;
foreach( $users as $row => $user ) {
foreach( $options as $row => $option ) {
if( isset( $option["username"] ) ) {
$convert = true;
break;
}
}
}
if( $convert ) {
//change project to users table
$result = $this->query( "ALTER TABLE user_options DROP COLUMN username", array(), array(), "rowCount", "exception" );
$result = $this->query( array(
"mysql" => "ALTER TABLE user_options ADD COLUMN user INT",
"pgsql" => 'ALTER TABLE user_options ADD COLUMN "user" INT',
), array(), array(), "rowCount", "exception" );
foreach( $users as $row => $user ) {
foreach( $options as $row => $option ) {
if( $option["username"] == $user["username"] ) {
$update_query = "";
if( DBTYPE == "mysql" ) {
$update_query = "UPDATE user_options SET user=? WHERE id=?;";
} else {
$update_query = "UPDATE user_options SET \"user\"=? WHERE id=?;";
}
$result = $this->query( $update_query, array( $user["id"], $option["id"] ), array(), "rowCount", "exception" );
}
}
}
} else {
$status_updates["username_user_option_column"] = array( "dev_message" => "User options username column needed no conversion." );
}
} catch( Exception $error ) {
//The access field is not there.
//echo var_export( $error->getMessage(), $access_query );
$status_updates["username_user_option_column"] = array(
"error_message" => $error->getMessage(),
"dev_message" => "No username column to convert."
);
}
try {
$result = $this->query( "ALTER TABLE users DROP COLUMN groups", array(), array(), "rowCount", "exception" );
$status_updates["users_groups_column"] = array( "dev_message" => "Removal of the groups column from the users table succeeded." );
} catch( Exception $error ) {
//echo var_dump( $error->getMessage() );
$status_updates["users_groups_column"] = array(
"error_message" => $error->getMessage(),
"dev_message" => "Removal of the groups column from the users table failed. This usually means there was never one to begin with"
);
}
try {
$update_query = "";
$users = $this->query( "SELECT id, access FROM users", array(), array(), "fetchAll", "exception" );
$convert = false;
foreach( $users as $row => $user ) {
if( ! is_numeric( $user["access"] ) ) {
$convert = true;
break;
}
}
if( $convert ) {
//change project to users table
$result = $this->query( "ALTER TABLE users DROP COLUMN access", array(), array(), "rowCount", "exception" );
$result = $this->query( "ALTER TABLE users ADD COLUMN access INT", array(), array(), "rowCount", "exception" );
foreach( $users as $row => $user ) {
if( in_array( $user["access"], array_keys( Permissions::SYSTEM_LEVELS ) ) ) {
$access = Permissions::SYSTEM_LEVELS[$user["access"]];
} elseif( is_numeric( $user["access"] ) ) {
$access = $user["access"];
} else {
$access = Permissions::SYSTEM_LEVELS["user"];
}
$update_query = "UPDATE users SET access=? WHERE id=?;";
$this->query( $update_query, array( $access, $user["id"] ), array(), "rowCount", "exception" );
}
} else {
$status_updates["users_access_column"] = array( "dev_message" => "No update needed." );
}
} catch( Exception $error ) {
$status_updates["path_owner_constraint"] = array(
"error_message" => $error->getMessage(),
"dev_message" => "Error changing access column from varchar to int"
);
}
try {
$projects = $this->query( array(
"mysql" => "ALTER TABLE projects DROP INDEX path1500owner255;",
"pgsql" => "ALTER TABLE projects DROP CONSTRAINT path1500owner255;",
), array(), 0, "rowCount", "exception" );
} catch( Exception $error ) {
//echo var_dump( $error->getMessage() );
$status_updates["path_owner_constraint"] = array(
"error_message" => $error->getMessage(),
"dev_message" => "Removal of path1500owner255 constraint in the projects table failed. This usually means there was never one to begin with"
);
}
try {
$convert = false;
$update_query = "";
$projects = $this->query( "SELECT id, name, path, owner FROM projects", array(), array(), "fetchAll", "exception" );
$users = $this->query( "SELECT id, username FROM users", array(), array(), "fetchAll", "exception" );
$delete = Permissions::LEVELS["delete"];
foreach( $projects as $row => $project ) {
if( ! is_numeric( $project["owner"] ) ) {
$convert = true;
}
}
if( $convert ) {
//change project to users table
$result = $this->query( "ALTER TABLE projects DROP COLUMN owner", array(), array(), "rowCount", "exception" );
$result = $this->query( "ALTER TABLE projects ADD COLUMN owner INT", array(), array(), "rowCount", "exception" );
foreach( $projects as $row => $project ) {
$current_user = null;
$bind_variables = array();
foreach( $users as $row => $user ) {
if( $project["owner"] == $user["username"] ) {
$current_user = $user;
break;
}
}
if( $current_user == null || $project["owner"] != $current_user["username"] ) {
$update_query = "UPDATE projects SET owner=? WHERE id=?;";
$bind_variables[] = -1;
$bind_variables[] = $project["id"];
} else {
$update_query = "UPDATE projects SET owner=? WHERE id=?;";
$bind_variables[] = $user["id"];
$bind_variables[] = $project["id"];
}
$result = $this->query( $update_query, $bind_variables, array(), "rowCount", "exception" );
}
} else {
$status_updates["owner_projects_column"] = array( "dev_message" => "User projects owner column needed no conversion." );
}
} catch( Exception $error ) {
//The access field is not there.
//echo var_export( $error->getMessage(), $access_query );
$status_updates["username_user_option_column"] = array(
"error_message" => $error->getMessage(),
"dev_message" => "No username column to convert."
);
}
try {
$projects = $this->query( array(
"mysql" => "ALTER TABLE active DROP INDEX username255path1500;",
"pgsql" => "ALTER TABLE active DROP CONSTRAINT username255path1500;",
), array(), 0, "rowCount", "exception" );
} catch( Exception $error ) {
//echo var_dump( $error->getMessage() );
$status_updates["username_path_constraint"] = array(
"error_message" => $error->getMessage(),
"dev_message" => "Removal of username255path1500 constraint in the active table failed. This usually means there was never one to begin with"
);
}
try {
$result = $this->query( "DELETE FROM active;", array(), 0, "rowCount", "exception" );
$result = $this->query( "ALTER TABLE active DROP COLUMN username;", array(), 0, "rowCount", "exception" );
$result = $this->query( array(
"mysql" => "ALTER TABLE active ADD COLUMN user INT",
"pgsql" => 'ALTER TABLE active ADD COLUMN "user" INT',
), array(), array(), "rowCount", "exception" );
} catch( Exception $error ) {
//echo var_dump( $error->getMessage() );
$status_updates["username_active_coluin"] = array(
"error_message" => $error->getMessage(),
"dev_message" => "Removal of username255path1500 constraint in the active table failed. This usually means there was never one to begin with"
);
}
}
return $status_updates;
}
public function query( $query, $bind_variables, $default, $action='fetchAll', $errors="default" ) {
/**
* Errors:
* default - this value could be anything such as true or foobar
* message
* exception
*/
if( is_array( $query ) ) {
if( in_array( DBTYPE, array_keys( $query ) ) ) {
$query = $query[DBTYPE];
} else {
if( isset( $query["*"] ) ) {
$query = $query["*"];
} else {
$return = $default;
if( $errors == "message" ) {
$return = json_encode( array( "error" => "No query specified for database type." ) );
} elseif( $errors == "exception" ) {
throw new Error( "No query specified for database type." );
}
return $return;
}
}
}
try {
$connection = $this->connect();
$statement = $connection->prepare( $query );
@ -242,6 +506,11 @@ class sql {
$return = $statement->rowCount();
break;
case( 'fetch' ):
$return = $statement->fetch( \PDO::FETCH_ASSOC );
break;
case( 'fetchAll' ):
$return = $statement->fetchAll( \PDO::FETCH_ASSOC );
@ -257,23 +526,18 @@ class sql {
$return = $statement->fetchAll( \PDO::FETCH_ASSOC );
break;
}
} catch( exception $error ) {
$error = $statement->errorInfo();
if( ! $error[0] == "00000" ) {
echo var_export( $error );
echo var_export( $return );
$return = $default;
if( $errors == "message" ) {
$return = json_encode( array( $error->getMessage() ) );
} elseif( $errors == "exception" ) {
throw $error;
}
if( $show_errors ) {
$return = json_encode( $error );
}
//echo var_dump( $error, $return );
$this->close();
return( $return );
}

View file

@ -0,0 +1,79 @@
--
-- Table structure for table `access`
--
CREATE TABLE IF NOT EXISTS `access` (
`user` int NOT NULL,
`project` int NOT NULL,
`level` int NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Table structure for table `active`
--
CREATE TABLE IF NOT EXISTS `active` (
`user` int NOT NULL,
`path` text NOT NULL,
`position` varchar(255) DEFAULT NULL,
`focused` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Table structure for table `options`
--
CREATE TABLE IF NOT EXISTS `options` (
`id` int PRIMARY KEY AUTO_INCREMENT NOT NULL,
`name` varchar(255) UNIQUE NOT NULL,
`value` text NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Table structure for table `projects`
--
CREATE TABLE IF NOT EXISTS `projects` (
`id` int PRIMARY KEY AUTO_INCREMENT NOT NULL,
`name` varchar(255) NOT NULL,
`path` text NOT NULL,
`owner` int NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Table structure for table `users`
--
CREATE TABLE IF NOT EXISTS `users` (
`id` int PRIMARY KEY AUTO_INCREMENT NOT NULL,
`first_name` varchar(255) DEFAULT NULL,
`last_name` varchar(255) DEFAULT NULL,
`username` varchar(255) NOT NULL,
`password` text NOT NULL,
`email` varchar(255) DEFAULT NULL,
`project` int DEFAULT NULL,
`access` int NOT NULL,
`token` varchar(255) DEFAULT NULL,
UNIQUE KEY `username` ( `username` )
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Table structure for table `user_options`
--
CREATE TABLE IF NOT EXISTS `user_options` (
`id` int PRIMARY KEY AUTO_INCREMENT NOT NULL,
`name` varchar(255) NOT NULL,
`user` int NOT NULL,
`value` text NOT NULL,
UNIQUE KEY `name_user` (`name`,`user`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

View file

@ -0,0 +1,78 @@
--
-- Table structure for table active
--
CREATE TABLE IF NOT EXISTS active (
"user" integer NOT NULL,
path text NOT NULL,
position varchar(255) DEFAULT NULL,
focused varchar(255) NOT NULL
);
--
-- Table structure for table access
--
CREATE TABLE IF NOT EXISTS access (
"user" integer NOT NULL,
project integer NOT NULL,
level integer NOT NULL
);
-- --------------------------------------------------------
--
-- Table structure for table options
--
CREATE TABLE IF NOT EXISTS options (
id SERIAL PRIMARY KEY,
name varchar(255) UNIQUE NOT NULL,
value text NOT NULL
);
-- --------------------------------------------------------
--
-- Table structure for table projects
--
CREATE TABLE IF NOT EXISTS projects (
id SERIAL PRIMARY KEY,
name varchar(255) NOT NULL,
path text NOT NULL,
owner integer NOT NULL
);
-- --------------------------------------------------------
--
-- Table structure for table users
--
CREATE TABLE IF NOT EXISTS users (
id SERIAL PRIMARY KEY,
first_name varchar(255) DEFAULT NULL,
last_name varchar(255) DEFAULT NULL,
username varchar(255) UNIQUE NOT NULL,
password text NOT NULL,
email varchar(255) DEFAULT NULL,
project integer DEFAULT NULL,
access integer NOT NULL,
token varchar(255) DEFAULT NULL
);
-- --------------------------------------------------------
--
-- Table structure for table user_options
--
CREATE TABLE IF NOT EXISTS user_options (
id SERIAL PRIMARY KEY,
name varchar(255) NOT NULL,
"user" integer NOT NULL,
value text NOT NULL,
UNIQUE (name,"user")
);

View file

@ -1,9 +1,18 @@
<?php
require_once('../../common.php');
if ( ! isset( $_POST['action'] ) ) {
if ( ! isset( $_POST['action'] ) && ! isset( $_GET['action'] ) ) {
die( formatJSEND( "error", "Missing parameter" ) );
} else {
if( isset( $_POST["action"] ) ) {
$action = $_POST["action"];
} else {
$action = $_GET["action"];
}
}
//////////////////////////////////////////////////////////////////
@ -12,22 +21,43 @@ if ( ! isset( $_POST['action'] ) ) {
checkSession();
if ( $_POST['action'] == 'create_default_tables' ) {
switch( $action ) {
case( "create_default_tables" ):
if( is_admin() ) {
global $sql;
$result = $sql->create_default_tables();
//echo var_dump( $result );
if( $result === true ) {
exit( formatJSEND( "success", "Created tables." ) );
} else {
exit( formatJSEND( "error", "Could not create tables." ) );
exit( formatJSEND( "error", array( "message" => "Could not create tables.", "result" => $result ) ) );
}
} else {
exit( formatJSEND( "error", "Only admins can use this method." ) );
}
break;
case( "get_ini_setting" ):
if( isset( $_POST["option"] ) ) {
$option = $_POST["option"];
} else {
$option = $_GET["option"];
}
exit( json_encode( array(
"option" => $option,
"value" => ini_get( $option ),
)));
break;
}

View file

@ -12,7 +12,7 @@ class Update {
// CONSTANTS
//////////////////////////////////////////////////////////////////
CONST VERSION = "v.2.9.5";
CONST VERSION = "v.3.0.0";
//////////////////////////////////////////////////////////////////
// PROPERTIES

View file

@ -66,11 +66,11 @@ switch($_GET['action']){
?>
<br><br><b><label><?php echo htmlentities("Your current version of Codiad is up to date."); ?></label></b>
<?php
if( $vars[0]['data']['name'] != '' ) {
/*if( $vars[0]['data']['name'] != '' ) {
?>
<em><?php i18n("Last update was done by "); ?><?php echo $vars[0]['data']['name']; ?>.</em>
<?php
}
}*/
}
?>
<?php

View file

@ -41,7 +41,7 @@
$('#modal-content form')
.die('submit'); // Prevent form bubbling
codiad.modal.load(500, this.dialog + '?action=check');
$('#modal-content').html('<div id="modal-loading"></div><div align="center">' + i18n("Contacting GitHub...") + '</div><br>');
$('#modal-content').html('<div id="modal-loading"></div><div align="center">' + i18n("Contacting Git Server...") + '</div><br>');
},
check_for_update: function () {

View file

@ -8,13 +8,28 @@ require_once('../../common.php');
require_once('../settings/class.settings.php');
require_once('./class.update.php');
function check_access_legacy() {
$pass = false;
if( isset( $_SESSION["token"] ) && isset( $_SESSION["user"] ) ) {
global $sql;
$query = "SELECT COUNT( * ) FROM users WHERE username=? AND access=?;";
$bind_variables = array( $_SESSION["user"], "admin" );
$return = $sql->query( $query, $bind_variables, -1, 'fetchColumn' );
$admin = ( $return > 0 );
return $admin;
}
return $pass;
}
$user_settings_file = BASE_PATH . "/data/settings.php";
$projects_file = BASE_PATH . "/data/projects.php";
$users_file = BASE_PATH . "/data/users.php";
//checkSession();
if ( ! checkAccess() ) {
if ( ! checkAccess() && ! check_access_legacy() ) {
echo "Error, you do not have access to update Codiad.";
exit();
}
@ -177,6 +192,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() {
@ -453,7 +474,6 @@ class updater {
$this->backup();
try {
$sessions = "../../data/sessions";
@ -476,10 +496,14 @@ class updater {
$this->path . "/components/autocomplete",
$this->path . "/plugins/auto_save",
$this->path . "/plugins/Codiad-Archives",
$this->path . "/plugins/Codiad-Archives-master",
$this->path . "/plugins/Codiad-Auto-Save",
$this->path . "/plugins/Codiad-Auto-Save-master",
$this->path . "/plugins/Codiad-CodeSettings",
$this->path . "/plugins/Codiad-CodeSettings-master",
$this->path . "/plugins/Codiad-DragDrop",
$this->path . "/plugins/Codiad-DragDrop-master",
);
foreach( $folder_conflictions as $dir ) {
@ -513,7 +537,9 @@ class updater {
$this->path . "/{$update_folder}/.gitignore",
$this->path . "/.gitlab-ci.yml",
$this->path . "/{$update_folder}/.gitlab-ci.yml"
$this->path . "/{$update_folder}/.gitlab-ci.yml",
$this->path . "/components/sql/class.sql.conversions.php",
);
foreach( $file_conflictions as $file ) {
@ -923,7 +949,7 @@ if( isset( $_GET["action"] ) && $_GET["action"] !== '' ) {
return;
}
progress.innerText = "Filesystem update finished. Please wait, your browser will now reload and start the datbase update.";
progress.innerText = "Filesystem update finished. Please wait, your browser will now reload and start the database update.";
setTimeout( function() {
@ -992,7 +1018,7 @@ if( isset( $_GET["action"] ) && $_GET["action"] !== '' ) {
return;
}
progress.innerText = "Filesystem update finished. Please wait, your browser will now reload and start the datbase update.";
progress.innerText = "Filesystem update finished. Please wait, your browser will now reload and start the database update.";
setTimeout( function() {

View file

@ -10,25 +10,10 @@ require_once( "../settings/class.settings.php" );
class User {
const ACCESS = array(
"admin",
"user"
);
//////////////////////////////////////////////////////////////////
// PROPERTIES
//////////////////////////////////////////////////////////////////
public $access = 'user';
public $username = '';
public $password = '';
public $project = '';
public $projects = '';
public $users = '';
public $actives = '';
public $lang = '';
public $theme = '';
//////////////////////////////////////////////////////////////////
// METHODS
//////////////////////////////////////////////////////////////////
@ -43,62 +28,65 @@ class User {
}
public function add_user() {
public function add_user( $username, $password, $access ) {
global $sql;
$query = "INSERT INTO users( username, password, access, project ) VALUES ( ?, ?, ?, ? );";
$bind_variables = array( $this->username, $this->password, $this->access, null );
$bind_variables = array( $username, $password, $access, null );
$return = $sql->query( $query, $bind_variables, 0, "rowCount" );
$pass = false;
if( $return > 0 ) {
$this->set_default_options();
echo formatJSEND( "success", array( "username" => $this->username ) );
} else {
echo formatJSEND( "error", "The Username is Already Taken" );
$this->set_default_options( $username );
$pass = true;
}
return $pass;
}
public function delete_user() {
public function delete_user( $username ) {
global $sql;
$query = "DELETE FROM user_options WHERE username=?;";
$bind_variables = array( $this->username );
$query = "DELETE FROM user_options WHERE user=( SELECT id FROM users WHERE username=? );";
$bind_variables = array( $username );
$return = $sql->query( $query, $bind_variables, -1, "rowCount" );
if( $return > -1 ) {
$query = "DELETE FROM projects WHERE owner=? AND access IN ( ?,?,?,?,? );";
$query = "
DELETE FROM projects
WHERE owner=( SELECT id FROM users WHERE username=? )
AND (
SELECT COUNT(*)
FROM access
WHERE project = projects.id
AND user <> ( SELECT id FROM users WHERE username=? )
) = 0;";
$bind_variables = array(
$this->username,
"null",
null,
"[]",
"",
json_encode( array( $this->username ) )
$username,
$username
);
$return = $sql->query( $query, $bind_variables, -1, "rowCount" );
if( $return > -1 ) {
$query = "DELETE FROM users WHERE username=?;";
$bind_variables = array( $this->username );
$bind_variables = array( $username );
$return = $sql->query( $query, $bind_variables, 0, "rowCount" );
if( $return > 0 ) {
echo formatJSEND( "success", null );
exit( formatJSEND( "success", null ) );
} else {
echo formatJSEND( "error", "Error deleting user information." );
exit( formatJSEND( "error", "Error deleting user information." ) );
}
} else {
echo formatJSEND( "error", "Error deleting user project information." );
exit( formatJSEND( "error", "Error deleting user project information." ) );
}
} else {
echo formatJSEND( "error", "Error deleting user option information." );
exit( formatJSEND( "error", "Error deleting user option information." ) );
}
}
@ -107,15 +95,8 @@ class User {
global $sql;
$query = "SELECT * FROM users WHERE username=?";
$bind_variables = array( $username );
$return = $sql->query( $query, $bind_variables, array() );
if( ! empty( $return ) ) {
echo formatJSEND( "success", $return );
} else {
echo formatJSEND( "error", "Could not select user." );
}
$return = $sql->query( $query, $bind_variables, array(), "fetch" );
return $return;
}
public function list_users() {
@ -134,26 +115,26 @@ class User {
}
}
public function set_default_options() {
public function set_default_options( $username ) {
foreach( Settings::DEFAULT_OPTIONS as $id => $option ) {
global $sql;
$query = "INSERT INTO user_options ( name, username, value ) VALUES ( ?, ?, ? );";
$query = "INSERT INTO user_options ( name, user, value ) VALUES ( ?, ( SELECT id FROM users WHERE username=? ), ? );";
$bind_variables = array(
$option["name"],
$this->username,
$username,
$option["value"],
);
$result = $sql->query( $query, $bind_variables, 0, "rowCount" );
if( $result == 0 ) {
$query = "UPDATE user_options SET value=? WHERE name=? AND username=?;";
$query = "UPDATE user_options SET value=? WHERE name=? AND user=( SELECT id FROM users WHERE username=? );";
$bind_variables = array(
$option["value"],
$option["name"],
$this->username,
$username,
);
$result = $sql->query( $query, $bind_variables, 0, "rowCount" );
}
@ -164,59 +145,18 @@ class User {
// Authenticate
//////////////////////////////////////////////////////////////////
public function Authenticate() {
public function Authenticate( $username, $password ) {
if( $this->username == "" || $this->password == "" ) {
if( $username == "" || $password == "" ) {
exit( formatJSEND( "error", "Username or password can not be blank." ) );
}
if( ! is_dir( SESSIONS_PATH ) ) {
mkdir( SESSIONS_PATH, 00755 );
}
$permissions = array(
"755",
"0755"
);
$server_user = posix_getpwuid( posix_geteuid() );
$sessions_permissions = substr( sprintf( '%o', fileperms( SESSIONS_PATH ) ), -4 );
$sessions_owner = posix_getpwuid( fileowner( SESSIONS_PATH ) );
if( is_array( $server_user ) ) {
$server_user = $server_user["uid"];
}
if( ! ( $sessions_owner === $server_user ) ) {
try {
chown( SESSIONS_PATH, $server_user );
} catch( Exception $e ) {
exit( formatJSEND("error", "Error, incorrect owner of sessions folder. Expecting: $server_user, Recieved: " . $sessions_owner ) );
}
}
if( ! in_array( $sessions_permissions, $permissions ) ) {
try {
chmod( SESSIONS_PATH, 00755 );
} catch( Exception $e ) {
exit( formatJSEND("error", "Error, incorrect permissions on sessions folder. Expecting: 0755, Recieved: " . $sessions_permissions ) );
}
return false;
}
global $sql;
$pass = false;
$this->EncryptPassword();
$password = $this->encrypt_password( $password );
$query = "SELECT * FROM users WHERE username=? AND password=?;";
$bind_variables = array( $this->username, $this->password );
$bind_variables = array( $username, $password );
$return = $sql->query( $query, $bind_variables, array() );
/**
@ -226,52 +166,46 @@ class User {
if( ( strtolower( DBTYPE ) == "mysql" ) && empty( $return ) ) {
$query = "SELECT * FROM users WHERE username=? AND password=PASSWORD( ? );";
$bind_variables = array( $this->username, $this->password );
$bind_variables = array( $username, $password );
$return = $sql->query( $query, $bind_variables, array() );
if( ! empty( $return ) ) {
$query = "UPDATE users SET password=? WHERE username=?;";
$bind_variables = array( $this->password, $this->username );
$bind_variables = array( $password, $username );
$return = $sql->query( $query, $bind_variables, array() );
$query = "SELECT * FROM users WHERE username=? AND password=?;";
$bind_variables = array( $this->username, $this->password );
$bind_variables = array( $username, $password );
$return = $sql->query( $query, $bind_variables, array() );
}
}
if( ! empty( $return ) ) {
$user = $return[0];
$pass = true;
$token = mb_strtoupper( strval( bin2hex( openssl_random_pseudo_bytes( 16 ) ) ) );
$_SESSION['id'] = SESSION_ID;
$_SESSION['user'] = $this->username;
$_SESSION['user'] = $username;
$_SESSION['user_id'] = $user["id"];
$_SESSION['token'] = $token;
$_SESSION['lang'] = $this->lang;
$_SESSION['theme'] = $this->theme;
$_SESSION["login_session"] = true;
$user = $return[0];
$query = "UPDATE users SET token=? WHERE username=?;";
$bind_variables = array( sha1( $token ), $this->username );
$bind_variables = array( sha1( $token ), $username );
$return = $sql->query( $query, $bind_variables, 0, 'rowCount' );
$projects = $sql->query( "SELECT path FROM projects WHERE id = ?", array( $user["project"] ), array() );
if( isset( $user['project'] ) && $user['project'] != '' ) {
if( isset( $user['project'] ) && $user['project'] != '' && ! empty( $projects ) ) {
$_SESSION['project'] = $user['project'];
$_SESSION['project'] = $projects[0]["path"];
$_SESSION['project_id'] = $user['project'];
}
$this->checkDuplicateSessions( $this->username );
}
if( $pass ) {
echo formatJSEND( "success", array( "username" => $this->username ) );
} else {
echo formatJSEND( "error", "Incorrect Username or Password" );
$this->checkDuplicateSessions( $username );
}
return $pass;
}
/**
@ -353,28 +287,31 @@ class User {
// Create Account
//////////////////////////////////////////////////////////////////
public function Create() {
public function Create( $username, $password ) {
$this->EncryptPassword();
$this->add_user();
$username = self::CleanUsername( $username );
$password = $this->encrypt_password( $password );
$result = $this->add_user( $username, $password, Permissions::SYSTEM_LEVELS["user"] );
return $result;
}
//////////////////////////////////////////////////////////////////
// Delete Account
//////////////////////////////////////////////////////////////////
public function Delete() {
public function Delete( $username ) {
$this->delete_user();
$username = self::CleanUsername( $username );
return $this->delete_user( $username );
}
//////////////////////////////////////////////////////////////////
// Encrypt Password
//////////////////////////////////////////////////////////////////
private function EncryptPassword() {
private function encrypt_password( $password ) {
$this->password = sha1( md5( $this->password ) );
return sha1( md5( $password ) );
}
//////////////////////////////////////////////////////////////////
@ -384,10 +321,10 @@ class User {
public function Password() {
global $sql;
$this->EncryptPassword();
$password = $this->encrypt_password( $this->password );
$query = "UPDATE users SET password=? WHERE username=?;";
$bind_variables = array( $this->password, $this->username );
$return = $sql->query( $query, $bind_variables, 0, "rowCount" );
$bind_variables = array( $password, $this->username );
$return = $sql->query( $query, $bind_variables, 0, "rowCount", "exception" );
if( $return > 0 ) {
@ -418,19 +355,19 @@ class User {
}
}
public function update_access() {
public function update_access( $username, $access ) {
global $sql;
$query = "UPDATE users SET access=? WHERE username=?;";
$bind_variables = array( $this->access, $this->username );
$bind_variables = array( $access, $username );
$return = $sql->query( $query, $bind_variables, 0, "rowCount" );
if( $return > 0 ) {
echo formatJSEND( "success", "Updated access for {$this->username}" );
echo formatJSEND( "success", "Updated access for {$username}" );
} else {
echo formatJSEND( "error", "Error updating project" );
echo formatJSEND( "error", "Error updating access" );
}
}

View file

@ -10,6 +10,7 @@
require_once('class.user.php');
if( ! isset( $_GET['action'] ) ) {
die( formatJSEND( "error", "Missing parameter" ) );
}
@ -18,6 +19,7 @@ if (!isset($_GET['action'])) {
//////////////////////////////////////////////////////////////////
if( $_GET['action'] != 'authenticate' ) {
checkSession();
}
@ -28,25 +30,79 @@ if ($_GET['action']!='authenticate') {
//////////////////////////////////////////////////////////////////
if($_GET['action']=='authenticate') {
if( ! isset( $_POST['username'] ) || ! isset( $_POST['password'] ) ) {
die( formatJSEND( "error", "Missing username or password" ) );
}
$User->username = User::CleanUsername( $_POST['username'] );
$User->password = $_POST['password'];
$username = User::CleanUsername( $_POST['username'] );
$password = $_POST['password'];
// check if the asked languages exist and is registered in languages/code.php
require_once '../../languages/code.php';
if( isset( $languages[$_POST['language']] ) ) {
$User->lang = $_POST['language'];
$lang = $_POST['language'];
} else {
$User->lang = 'en';
$lang = 'en';
}
// theme
$User->theme = $_POST['theme'];
$theme = $_POST['theme'];
$permissions = array(
"755",
"0755"
);
$User->Authenticate();
if( ! is_dir( SESSIONS_PATH ) ) {
mkdir( SESSIONS_PATH, 00755 );
}
$server_user = getmyuid();
$sessions_permissions = substr( sprintf( '%o', fileperms( SESSIONS_PATH ) ), -4 );
$sessions_owner = fileowner( SESSIONS_PATH );
if( is_array( $server_user ) ) {
$server_user = $server_user["uid"];
}
if( ! ( $sessions_owner === $server_user ) ) {
try {
chown( SESSIONS_PATH, $server_user );
} catch( Exception $e ) {
exit( formatJSEND("error", "Error, incorrect owner of sessions folder. Expecting: $server_user, Recieved: " . $sessions_owner ) );
}
}
if( ! in_array( $sessions_permissions, $permissions ) ) {
try {
chmod( SESSIONS_PATH, 00755 );
} catch( Exception $e ) {
exit( formatJSEND("error", "Error, incorrect permissions on sessions folder. Expecting: 0755, Recieved: " . $sessions_permissions ) );
}
}
$pass = $User->Authenticate( $username, $password );
if( $pass ) {
$_SESSION['lang'] = $lang;
$_SESSION['theme'] = $theme;
exit( formatJSEND( "success", array( "username" => $username ) ) );
} else {
exit( formatJSEND( "error", "Incorrect Username or Password" ) );
}
}
//////////////////////////////////////////////////////////////////
@ -63,14 +119,33 @@ if ($_GET['action']=='logout') {
//////////////////////////////////////////////////////////////////
if( $_GET['action'] == 'create' ) {
if( checkAccess() ) {
if ( ! isset( $_POST['username'] ) || ! isset( $_POST['password'] ) ) {
die(formatJSEND("error", "Missing username or password"));
exit( formatJSEND( "error", "Missing username or password" ) );
}
$User->username = User::CleanUsername( $_POST['username'] );
$User->password = $_POST['password'];
$User->Create();
if ( ! ( $_POST['password'] === $_POST['password2'] ) ) {
exit( formatJSEND( "error", "Passwords do not match" ) );
}
if ( preg_match( '/[^\w\-\._@]/', $_POST['username'] ) ) {
exit( formatJSEND( "error", "Invalid characters in username" ) );
}
$result = $User->Create( $_POST['username'], $_POST['password'] );
if( $result ) {
exit( formatJSEND( "success", "User successfully created." ) );
} else {
exit( formatJSEND( "error", "User could not be created." ) );
}
}
}
@ -79,13 +154,16 @@ if ($_GET['action']=='create') {
//////////////////////////////////////////////////////////////////
if( $_GET['action'] == 'delete' ) {
if( checkAccess() ) {
if( ! isset( $_GET['username'] ) ) {
die(formatJSEND("error", "Missing username"));
exit( formatJSEND( "error", "Missing username" ) );
}
$User->username = User::CleanUsername( $_GET['username'] );
$User->Delete();
$return = $User->Delete( $_GET['username'] );
exit( json_encode( $return ) );
}
}
@ -94,11 +172,14 @@ if ($_GET['action']=='delete') {
//////////////////////////////////////////////////////////////////
if( $_GET['action'] == 'password' ) {
if( ! isset( $_POST['username']) || ! isset( $_POST['password'] ) ) {
die( formatJSEND( "error", "Missing username or password" ) );
}
if (checkAccess() || $_POST['username'] == $_SESSION['user']) {
if( $_POST['username'] == $_SESSION['user'] || is_admin() ) {
$User->username = User::CleanUsername( $_POST['username'] );
$User->password = $_POST['password'];
$User->Password();
@ -110,7 +191,9 @@ if ($_GET['action']=='password') {
//////////////////////////////////////////////////////////////////
if( $_GET['action'] == 'project' ) {
if( ! isset( $_GET['project'] ) ) {
die( formatJSEND( "error", "Missing project" ) );
}
@ -129,6 +212,7 @@ if ( $_GET['action'] == 'search_users' ) {
die( formatJSEND( "error", "Missing search term" ) );
}
search_users( $_GET['search_term'], "exit", true );
}
@ -139,7 +223,6 @@ if ( $_GET['action'] == 'search_users' ) {
if( $_GET['action'] == 'verify' ) {
$User->username = $_SESSION['user'];
//$User->Verify();
checkSession();
}
@ -148,17 +231,20 @@ if ( $_GET['action'] == 'update_access' ) {
checkSession();
if ( ! isset( $_GET['access'] ) || ! isset( $_GET['username'] ) ) {
if( ! isset( $_POST['access'] ) || ! isset( $_POST['user'] ) ) {
die( formatJSEND( "error", "Could not update access." ) );
}
if( ! is_admin() ) {
die( formatJSEND( "error", "You do not have permission to update access." ) );
die( formatJSEND( "error", "You do not have permission to update user's access." ) );
}
$User->username = $_GET["username"];
$User->access = $_GET["access"];
$User->update_access();
if( ! in_array( $_POST["access"], array_keys( Permissions::SYSTEM_LEVELS ) ) ) {
exit( formatJSEND( "error", "Invalid access level specified." ) );
}
$User->update_access( $_POST["user"], Permissions::SYSTEM_LEVELS["{$_POST["access"]}"] );
}

View file

@ -72,10 +72,10 @@ switch($_GET['action']){
<td width="75">
<select onchange="codiad.user.update_access( event, '<?php echo( $data['username'] ); ?>' )">
<?php
foreach( User::ACCESS as $role ) {
foreach( Permissions::SYSTEM_LEVELS as $role => $id ) {
?>
<option value="<?php echo $role;?>" <?php if( $data["access"] == $role ) { echo 'selected="selected"'; }?>><?php echo i18n( $role );?></option>
<option value="<?php echo $role;?>" <?php if( $data["access"] == $id ) { echo 'selected="selected"'; }?>><?php echo i18n( $role );?></option>
<?php
}
?>

View file

@ -142,25 +142,26 @@
// Check matching passwords
if(password1 != password2) {
codiad.message.error(i18n('Passwords Do Not Match'));
pass = false;
}
// Check no spaces in username
if(!/^[a-z0-9]+$/i.test(username) || username.length === 0) {
codiad.message.error(i18n('Username Must Be Alphanumeric String'));
pass = false;
}
if( pass ) {
$.post( _this.controller + '?action=create', {
'username': username,
'password': password1
'password': password1,
'password2': password2,
}, function(data) {
var createResponse = codiad.jsend.parse( data );
if( createResponse != 'error' ) {
codiad.message.success( i18n( 'User Account Created' ) )
_this.list();
} else {
console.log( createResponse, data );
}
});
}
@ -185,6 +186,9 @@
if(deleteResponse != 'error') {
codiad.message.success(i18n('Account Deleted'))
_this.list();
} else {
console.log( deleteResponse, data );
}
});
});
@ -254,6 +258,9 @@
if(passwordResponse != 'error') {
codiad.message.success(i18n('Password Changed'));
codiad.modal.unload();
} else {
console.log( passwordResponse, data );
}
});
}
@ -268,7 +275,7 @@
$.get(this.controller + '?action=project&project=' + project);
},
update_access: function( e, username=null ) {
update_access: function( e, username ) {
let access = "";
@ -277,10 +284,13 @@
access = e;
} else {
access = e.target.value;
access = $( e.target ).val();
}
$.get( this.controller + `?action=update_access&username=${username}&access=${access}`, function( data ) {
$.post( this.controller + `?action=update_access`, {
user: username,
access: access,
}, function( data ) {
let response = codiad.jsend.parse( data );
if( response != 'error' ) {

219
index.php
View file

@ -18,6 +18,7 @@ $themes = Common::readDirectory(THEMES);
// Theme
$theme = THEME;
if( isset( $_SESSION['theme'] ) ) {
$theme = $_SESSION['theme'];
}
@ -31,7 +32,8 @@ if( defined( "SITE_NAME" ) && ! ( SITE_NAME === "" || SITE_NAME === null ) ) {
}
?>
<!doctype html>
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
@ -41,22 +43,31 @@ if( defined( "SITE_NAME" ) && ! ( SITE_NAME === "" || SITE_NAME === null ) ) {
$stylesheets = array("jquery.toastmessage.css","reset.css","fonts.css","screen.css");
foreach( $stylesheets as $sheet ) {
if( file_exists( THEMES . "/". $theme . "/".$sheet ) ) {
echo( '<link rel="stylesheet" href="themes/' . $theme . '/' . $sheet . '">' );
} else {
echo( '<link rel="stylesheet" href="themes/default/'.$sheet.'?v=' . get_version() . '">' );
}
}
// Load Component CSS Files
foreach( $components as $component ) {
if( file_exists( THEMES . "/". $theme . "/" . $component . "/screen.css" ) ) {
echo('<link rel="stylesheet" href="themes/'.$theme.'/'.$component.'/screen.css">');
} else {
if( file_exists( "themes/default/" . $component . "/screen.css" ) ) {
echo( '<link rel="stylesheet" href="themes/default/' . $component . '/screen.css?v=' . get_version() . '">' );
} else {
if( file_exists( COMPONENTS . "/" . $component . "/screen.css" ) ) {
echo( '<link rel="stylesheet" href="components/' . $component . '/screen.css">' );
}
}
@ -65,13 +76,19 @@ if( defined( "SITE_NAME" ) && ! ( SITE_NAME === "" || SITE_NAME === null ) ) {
// Load Plugin CSS Files
foreach( $plugins as $plugin ) {
if( file_exists( THEMES . "/". $theme . "/" . $plugin . "/screen.css" ) ) {
echo( '<link rel="stylesheet" href="themes/'.$theme.'/'.$plugin.'/screen.css">' );
} else {
if( file_exists( "themes/default/" . $plugin . "/screen.css" ) ) {
echo( '<link rel="stylesheet" href="themes/default/' . $plugin . '/screen.css">' );
} else {
if( file_exists( PLUGINS . "/" . $plugin . "/screen.css" ) ) {
echo( '<link rel="stylesheet" href="plugins/' . $plugin . '/screen.css">' );
}
}
@ -80,22 +97,24 @@ if( defined( "SITE_NAME" ) && ! ( SITE_NAME === "" || SITE_NAME === null ) ) {
?>
<link rel="icon" href="favicon.ico" type="image/x-icon" />
</head>
<body>
<script>
var i18n = (function(lang) {
let i18n = (
function( lang ) {
return function( word, args ) {
var x;
var returnw = (word in lang) ? lang[word] : word;
let x;
let returnw = ( word in lang ) ? lang[word] : word;
for( x in args ) {
returnw = returnw.replace( "%{"+x+"}%", args[x] );
}
return returnw;
}
})(<?php echo json_encode($lang); ?>)
}
)( <?php echo json_encode( $lang );?> )
</script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script>!window.jQuery && document.write(unescape('%3Cscript src="js/jquery-1.7.2.min.js"%3E%3C/script%3E'));</script>
<script src="js/jquery-1.7.2.min.js"></script>
<script src="js/jquery-ui-1.8.23.custom.min.js"></script>
<script src="js/jquery.css3.min.js"></script>
<script src="js/jquery.easing.js"></script>
@ -128,64 +147,78 @@ if( defined( "SITE_NAME" ) && ! ( SITE_NAME === "" || SITE_NAME === null ) ) {
// Installer
require_once('components/install/view.php');
} else {
// Login form
?>
<form id="login" method="post" style="position: fixed; width: 350px; top: 30%; left: 50%; margin-left: -175px; padding: 35px;">
<label>
<span class="icon-user login-icon"></span> <?php i18n("Username"); ?>
<span class="icon-user login-icon"></span>
<?php i18n("Username");?>
<input type="text" name="username" autofocus="autofocus" autocomplete="off">
</label>
<label>
<span class="icon-lock login-icon"></span> <?php i18n("Password"); ?>
<span class="icon-lock login-icon"></span>
<?php i18n("Password");?>
<input type="password" name="password">
<span class="icon-eye in-field-icon-right hide_field">
</label>
<div class="language-selector">
<label><span class="icon-picture login-icon"></span> <?php i18n("Theme"); ?></label>
<label>
<span class="icon-picture login-icon"></span>
<?php i18n("Theme");?>
</label>
<select name="theme" id="theme">
<option value="default"><?php i18n("Default");?></option>
<?php
include 'languages/code.php';
foreach($themes as $theme):
foreach( $themes as $theme ) {
if( file_exists( THEMES . "/" . $theme . "/theme.json" ) ) {
$data = file_get_contents(THEMES."/" . $theme . "/theme.json");
$data = json_decode($data,true);
?><option value="<?php echo $theme;?>" <?php if( $theme == THEME ) { echo "selected"; } ?>>
<?php if( $data[0]['name'] != '' ) { echo $data[0]['name']; } else { echo $theme; } ?>
</option>
<?php
}
};
?>
<option value="<?php echo $theme; ?>" <?php if($theme == THEME) { echo "selected"; } ?>><?php if($data[0]['name'] != '') { echo $data[0]['name']; } else { echo $theme; } ?></option>
<?php } endforeach; ?>
</select>
<label><span class="icon-language login-icon"></span> <?php i18n("Language"); ?></label>
<label>
<span class="icon-language login-icon"></span>
<?php i18n("Language"); ?>
</label>
<select name="language" id="language">
<?php
include 'languages/code.php';
foreach(glob("languages/*.php") as $filename):
foreach( glob( "languages/*.php" ) as $filename ) {
$lang_code = str_replace( array( "languages/", ".php" ), "", $filename );
if(!isset($languages[$lang_code])) continue;
if( ! isset( $languages[$lang_code] ) ) {
continue;
}
$lang_disp = ucfirst( strtolower( $languages[$lang_code] ) );
?>
<option value="<?php echo $lang_code; ?>" <?php if ($lang_code == "en"){echo "selected";}?>><?php echo $lang_disp; ?></option>
<?php endforeach; ?>
<option value="<?php echo $lang_code; ?>" <?php if( $lang_code == "en" ) { echo "selected"; }?>>
<?php echo $lang_disp;?>
</option>
<?php
}
?>
</select>
</div>
<button><?php i18n("Login"); ?></button>
<a class="show-language-selector"><?php i18n("More"); ?></a>
</form>
<script src="components/user/init.js"></script>
<script>
$( ".hide_field" ).on( "click", function( e ) {
let password = document.querySelector( "input[name='password']" );
console.log( password, password.type );
if( password.type == "password" ) {
password.type = "text";
@ -196,30 +229,28 @@ if( defined( "SITE_NAME" ) && ! ( SITE_NAME === "" || SITE_NAME === null ) ) {
});
</script>
<?php
}
} else {
//////////////////////////////////////////////////////////////////
// AUTHENTICATED
//////////////////////////////////////////////////////////////////
} else {
define( "USER_WORKSPACE", WORKSPACE . '/' . preg_replace( '/[^\w-]/', '', strtolower( $_SESSION["user"] ) ) );
if( ! is_dir( USER_WORKSPACE ) ) {
mkdir( USER_WORKSPACE, 0755 );
}
?>
<div id="workspace">
<div id="drop-overlay" class="drop-overlay"><span class="drop-overlay-message">Drop files or folders here.</span></div>
<div id="sb-left" class="sidebar">
<div id="sb-left-title">
<a id="lock-left-sidebar" class="icon-lock icon"></a>
<?php if (!common::isWINOS()) { ?>
<?php
if ( ! common::isWINOS() ) {
?>
<a id="finder-quick" class="icon icon-archive"></a>
<a id="tree-search" class="icon-search icon"></a>
<h2 id="finder-label"><?php i18n("Explore");?></h2>
@ -235,12 +266,12 @@ if( defined( "SITE_NAME" ) && ! ( SITE_NAME === "" || SITE_NAME === null ) ) {
<li><a data-action="search"><?php i18n("Search File Contents"); ?></a></li>
</ul>
</div>
<?php } ?>
<?php
}
?>
</div>
<div class="sb-left-content">
<div id="context-menu" data-path="" data-type="">
<?php
////////////////////////////////////////////////////////////
@ -250,21 +281,30 @@ if( defined( "SITE_NAME" ) && ! ( SITE_NAME === "" || SITE_NAME === null ) ) {
foreach( $context_menu as $menu_item => $data ) {
if( $data['title'] == 'Break' ) {
echo( '<hr class="' . $data['applies-to'] . '">' );
} else {
echo( '<a class="' . $data['applies-to'] . '" onclick="' . $data['onclick'] . '"><span class="' . $data['icon'] . '"></span>' . get_i18n( $data['title'] ) . '</a>' );
}
}
foreach( $plugins as $plugin ) {
if( file_exists( PLUGINS . "/" . $plugin . "/plugin.json" ) ) {
$pdata = file_get_contents( PLUGINS . "/" . $plugin . "/plugin.json" );
$pdata = json_decode( $pdata, true );
if( isset( $pdata[0]['contextmenu'] ) ) {
foreach( $pdata[0]['contextmenu'] as $contextmenu ) {
if( ( ! isset( $contextmenu['admin'] ) || ( $contextmenu['admin'] ) && checkAccess() ) || ! $contextmenu['admin'] ) {
if( isset( $contextmenu['applies-to'] ) && isset( $contextmenu['action'] ) && isset( $contextmenu['icon'] ) && isset( $contextmenu['title'] ) ) {
echo( '<hr class="' . $contextmenu['applies-to'] . '">' );
echo( '<a class="' . $contextmenu['applies-to'] . '" onclick="' . $contextmenu['action'] . '"><span class="' . $contextmenu['icon'] . '"></span>' . $contextmenu['title'] . '</a>' );
}
@ -273,20 +313,13 @@ if( defined( "SITE_NAME" ) && ! ( SITE_NAME === "" || SITE_NAME === null ) ) {
}
}
}
?>
</div>
<div id="file-manager"></div>
<div id="file-manager" class="file-manager"></div>
<ul id="list-active-files"></ul>
</div>
<div id="side-projects" class="sb-left-projects">
<div id="project-list" class="sb-project-list">
<div class="project-list-title">
<h2><?php i18n("Projects"); ?></h2>
<a id="projects-collapse" class="icon-down-dir icon" alt="<?php i18n("Collapse"); ?>"></a>
@ -295,18 +328,24 @@ if( defined( "SITE_NAME" ) && ! ( SITE_NAME === "" || SITE_NAME === null ) ) {
<a id="projects-create" class="icon-plus icon" alt="<?php i18n("Create Project"); ?>"></a>
<?php //} ?>
</div>
<div class="sb-projects-content"></div>
</div>
</div>
<div class="sidebar-handle"><span>||</span></div>
<div class="sidebar-handle">
<span>||</span>
</div>
</div>
<div class="uploads-container">
<div class="project-list-title" style="">
<h2><?php i18n( "Uploads" );?></h2>
<a id="uploads-close" class="icon-down-dir icon" alt="Collapse"></a>
</div>
<div class="uploads-content"></div>
</div>
<div id="uploads-button"><?php i18n("Uploads");?></div>
<div id="cursor-position">
<?php i18n("Ln"); ?>: 0 &middot; <?php i18n("Col"); ?>: 0
</div>
<div id="cursor-position"><?php i18n("Ln"); ?>: 0 &middot; <?php i18n("Col"); ?>: 0</div>
<div id="editor-region">
<div id="editor-top-bar">
<ul id="tab-list-active-files"></ul>
@ -319,12 +358,11 @@ if( defined( "SITE_NAME" ) && ! ( SITE_NAME === "" || SITE_NAME === null ) ) {
<ul id="dropdown-list-active-files"></ul>
<div class="bar"></div>
</div>
<div id="root-editor-wrapper"></div>
<div id="editor-bottom-bar">
<a id="settings" class="ico-wrapper"><span class="icon-doc-text"></span><?php i18n("Settings"); ?></a>
<a id="settings" class="ico-wrapper">
<span class="icon-doc-text"></span><?php i18n("Settings");?>
</a>
<?php
////////////////////////////////////////////////////////////
@ -332,13 +370,19 @@ if( defined( "SITE_NAME" ) && ! ( SITE_NAME === "" || SITE_NAME === null ) ) {
////////////////////////////////////////////////////////////
foreach( $plugins as $plugin ) {
if( file_exists( PLUGINS . "/" . $plugin . "/plugin.json" ) ) {
$pdata = file_get_contents( PLUGINS . "/" . $plugin . "/plugin.json" );
$pdata = json_decode( $pdata, true );
if( isset( $pdata[0]['bottombar'] ) ) {
foreach( $pdata[0]['bottombar'] as $bottommenu ) {
if( ( ! isset( $bottommenu['admin'] ) || ( $bottommenu['admin'] ) && checkAccess()) || ! $bottommenu['admin'] ) {
if( isset( $bottommenu['action'] ) && isset( $bottommenu['icon'] ) && isset( $bottommenu['title'] ) ) {
echo( '<div class="divider"></div>' );
echo( '<a onclick="' . $bottommenu['action'] . '"><span class="' . $bottommenu['icon'] . '"></span>' . $bottommenu['title'] . '</a>' );
}
@ -347,34 +391,33 @@ if( defined( "SITE_NAME" ) && ! ( SITE_NAME === "" || SITE_NAME === null ) ) {
}
}
}
?>
<div class="divider"></div>
<a id="split" class="ico-wrapper"><span class="icon-layout"></span><?php i18n("Split"); ?></a>
<div class="divider"></div>
<a id="current-mode"><span class="icon-layout"></span></a>
<a id="current-mode">
<span class="icon-layout"></span>
</a>
<div class="divider"></div>
<div id="current-file"></div>
</div>
<div id="changemode-menu" class="options-menu">
</div>
<div id="changemode-menu" class="options-menu"></div>
<ul id="split-options-menu" class="options-menu">
<li id="split-horizontally"><a> <?php i18n("Split Horizontally"); ?> </a></li>
<li id="split-vertically"><a> <?php i18n("Split Vertically"); ?> </a></li>
<li id="merge-all"><a> <?php i18n("Merge all"); ?> </a></li>
</ul>
</div>
<div id="sb-right" class="sidebar">
<div class="sidebar-handle"><span><a class="icon-menu"></a></span></div>
<div class="sidebar-handle">
<span>
<a class="icon-menu"></a>
</span>
</div>
<div id="sb-right-title">
<span id="lock-right-sidebar" class="icon-switch icon"></span>
</div>
<div class="sb-right-content">
<?php
////////////////////////////////////////////////////////////
@ -382,58 +425,72 @@ if( defined( "SITE_NAME" ) && ! ( SITE_NAME === "" || SITE_NAME === null ) ) {
////////////////////////////////////////////////////////////
foreach( $right_bar as $item_rb => $data ) {
if( ! isset( $data['admin'] ) ) {
$data['admin'] = false;
}
if( $data['title'] == 'break' ) {
if( ! $data['admin'] || $data['admin'] && checkAccess() ) {
echo( "<hr>" );
}
} elseif( $data['title'] != 'break' && $data['title'] != 'pluginbar' && $data['onclick'] == '' ) {
if( ! $data['admin'] || $data['admin'] && checkAccess() ) {
echo( "<hr><div class='sb-right-category'>" . get_i18n( $data['title'] ) . "</div>" );
}
} elseif( $data['title'] == 'pluginbar' ) {
if( ! $data['admin'] || $data['admin'] && checkAccess() ) {
foreach( $plugins as $plugin ) {
if( file_exists( PLUGINS . "/" . $plugin . "/plugin.json" ) ) {
$pdata = file_get_contents( PLUGINS . "/" . $plugin . "/plugin.json" );
$pdata = json_decode( $pdata, true );
if( isset( $pdata[0]['rightbar'] ) ) {
foreach( $pdata[0]['rightbar'] as $rightbar ) {
if( ( ! isset( $rightbar['admin'] ) || ( $rightbar['admin'] ) && checkAccess()) || ! $rightbar['admin'] ) {
if( isset( $rightbar['action'] ) && isset( $rightbar['icon'] ) && isset( $rightbar['title'] ) ) {
echo( '<a onclick="' . $rightbar['action'] . '"><span class="' . $rightbar['icon'] . '"></span>' . get_i18n( $rightbar['title'] ) . '</a>' );
}
}
}
//echo("<hr>");
}
}
}
}
} else {
if( ! $data['admin'] || $data['admin'] && checkAccess() ) {
echo( '<a onclick="' . $data['onclick'] . '"><span class="' . $data['icon'] . ' bigger-icon"></span>'. get_i18n( $data['title'] ) . '</a>' );
}
}
}
?>
</div>
</div>
</div>
<div id="modal-overlay"></div>
<div id="modal"><div id="close-handle" class="icon-cancel" onclick="codiad.modal.unload();"></div><div id="drag-handle" class="icon-location"></div><div id="modal-content"></div></div>
<div id="modal">
<div id="close-handle" class="icon-cancel" onclick="codiad.modal.unload();"></div>
<div id="drag-handle" class="icon-location"></div>
<div id="modal-content"></div>
</div>
<iframe id="download"></iframe>
<div id="autocomplete"><ul id="suggestions"></ul></div>
<div id="autocomplete">
<ul id="suggestions"></ul>
</div>
<!-- ACE -->
<script src="components/editor/ace-editor/ace.js"></script>
@ -456,19 +513,21 @@ if( defined( "SITE_NAME" ) && ! ( SITE_NAME === "" || SITE_NAME === null ) ) {
// JS
foreach( $components as $component ) {
if( file_exists( COMPONENTS . "/" . $component . "/init.js" ) ) {
echo( '<script src="components/' . $component . '/init.js"></script>"' );
}
}
foreach( $plugins as $plugin ) {
if( file_exists( PLUGINS . "/" . $plugin . "/init.js" ) ) {
echo( '<script src="plugins/' . $plugin . '/init.js"></script>"' );
}
}
}
?>
</body>
</html>

View file

@ -1,6 +1,6 @@
( function( global, $ ) {
var codiad = global.codiad;
let codiad = global.codiad;
//////////////////////////////////////////////////////////////////////
// Parse JSEND Formatted Returns
@ -11,7 +11,8 @@
parse: function( d ) {
// (Data)
var obj = $.parseJSON( d );
let obj = $.parseJSON( d );
if ( obj === undefined || obj === null ) {
return 'error';

View file

@ -21,8 +21,12 @@
load: function( width, url, data ) {
return new Promise( function( resolve, reject ) {
data = data || {};
var bounds = this._getBounds( width );
let _this = codiad.modal;
let bounds = _this._getBounds( width );
let content = $( '#modal-content' )
$('#modal')
.css({
'top': bounds.top,
@ -33,23 +37,26 @@
.draggable({
handle: '#drag-handle'
});
$('#modal-content')
.html('<div id="modal-loading"></div>');
this.load_process = $.get( url, data, function( data ) {
$('#modal-content').html( data );
content.html('<div id="modal-loading"></div>');
_this.load_process = $.get( url, data, function( data ) {
content.html( data );
// Fix for Firefox autofocus goofiness
$('input[autofocus="autofocus"]')
.focus();
});
var event = {animationPerformed: false};
$('#modal-content input[autofocus="autofocus"]').focus();
resolve( content );
}).error( reject );
let event = {animationPerformed: false};
amplify.publish( 'modal.onLoad', event );
// If no plugin has provided a custom load animation
if( ! event.animationPerformed ) {
$('#modal, #modal-overlay')
.fadeIn(200);
$('#modal, #modal-overlay').fadeIn(200);
}
codiad.sidebars.modalLock = true;
});
},
show_loading: function() {

View file

@ -135,15 +135,6 @@
},
success: function( data ) {
let response = codiad.jsend.parse( data );
if( response.status != 'error' ) {
codiad.message.success( i18n( 'Created Default Tables' ) );
} else {
codiad.message.error( i18n( 'Error Creating Default Tables' ) );
}
console.log( data );
},
error: function(jqXHR, textStatus, errorThrown) {
@ -158,6 +149,45 @@
},
});
},
get_ini_setting: async function( option ) {
let i = null;
let result = await jQuery.ajax({
url: this.controller,
type: "POST",
dataType: 'html',
data: {
action: 'get_ini_setting',
option: option,
},
success: function( data ) {
console.log( data );
},
error: function(jqXHR, textStatus, errorThrown) {
codiad.message.error( i18n( 'Error Creating Default Tables' ) );
console.log('jqXHR:');
console.log(jqXHR);
console.log('textStatus:');
console.log(textStatus);
console.log('errorThrown:');
console.log(errorThrown);
},
});
try {
let data = JSON.parse( result );
i = data.value;
} catch( e ) {
console.log( e, result );
}
return i;
}
};
})(this, jQuery);

View file

@ -1,4 +1,4 @@
#file-manager {
.file-manager {
width: 100%;
height: 100%;
float: left;
@ -6,32 +6,32 @@
padding: 15px 15px 30px 15px;
overflow: auto;
}
#file-manager ul {
.file-manager ul {
display: block;
margin: 0;
padding: 0;
}
#file-manager li {
.file-manager li {
display: block;
margin: 0;
padding: 2px 0;
list-style: none;
}
#file-manager ul ul li {
.file-manager ul ul li {
margin-left: 20px;
white-space: nowrap;
}
#file-manager a {
.file-manager a {
display: inline-block;
min-width: 100%;
cursor: pointer;
padding: 5px;
border-radius: 3px;
}
#file-manager a:hover, #file-manager a.context-menu-active {
.file-manager a:hover, .file-manager a.context-menu-active {
background-color: #333;
}
#file-manager span {
.file-manager span {
width:10px;
height:10px;
display: inline-block;
@ -39,43 +39,51 @@
padding-top: 0;
line-height: 6px;
}
#file-manager .plus:before {
.file-manager .plus:before {
display: block;
content: "\25b8";
padding: 5px;
margin-left: -10px;
font-size: 16px;
}
#file-manager .plus {
.file-manager .plus {
color: gray;
font-family: entypo;
font-style: normal;
display: inline-block;
}
#file-manager .none {
.file-manager .none {
background: none;
}
#file-manager .minus:before {
.file-manager .minus:before {
display: block;
content: "\25be";
padding: 5px;
margin-left: -10px;
font-size: 16px;
}
#file-manager .minus {
.file-manager .minus {
color: gray;
font-family: entypo;
font-style: normal;
display: inline-block;
}
#file-manager .plus:hover {
.file-manager .plus:hover {
cursor: pointer;
color: #fff;
}
#file-manager .minus:hover {
.file-manager .minus:hover {
cursor: pointer;
color: #fff;
}
.file-manager-selected {
background-color: #4a4a4a;
}
.file-manager-selected:hover {
background-color: #4a4a4a !important;
}
/* CONTEXT MENU */
#context-menu {
@ -143,66 +151,6 @@
float: right;
background: url(../loading.gif) no-repeat;
}
/* UPLOADER */
#upload-drop-zone {
height: 200px;
padding-top: 60px;
border: 1px solid #666;
border-radius: 5px;
margin: 10px 0;
box-shadow: inset 0px 0px 10px 0px rgba(0, 0, 0, .5);
text-align: center;
font-size: 25px;
color: #999;
}
.upload-drag-over {
border: 1px solid #fff;
}
#upload-wrapper {
cursor: pointer;
display: inline-block;
overflow: hidden;
position: relative;
}
#upload-clicker {
background: #333;
color: #999;
cursor: pointer;
display: inline-block;
}
#upload-wrapper:hover #upload-clicker {
color: #fff;
}
#upload-wrapper input {
cursor: pointer;
height: 100%;
position: absolute;
right: 0;
top: 0;
opacity: 0.0;
}
#upload-progress {
width: 75%;
margin: 10px auto;
height: 20px;
border: 1px solid #666;
background: #262626;
border-radius: 5px;
overflow: hidden;
}
#upload-progress .bar {
width: 0;
height: 20px;
background-image: url(images/progress_bar.png);
}
#upload-complete {
display: none;
font-size: 18px;
margin: 10px 0;
color: #fff;
}
/* SEARCH */
@ -214,210 +162,220 @@
/* ICONS */
#file-manager a {
.file-manager a {
background-repeat: no-repeat;
background-position: 4px 4px;
text-indent: 22px;
padding-top: 5px;
}
#file-manager .directory {
.file-manager .directory {
background-image: url(images/directory.png);
}
#file-manager .directory.open {
.file-manager .directory.open {
background-image: url(images/directory_open.png);
}
#file-manager .file {
.file-manager .file {
background-image: url(images/file.png);
}
/* EXTENSIONS */
#file-manager .ext-htaccess {
.file-manager .ext-htaccess {
background-image: url(images/config.png);
}
#file-manager .ext-conf {
.file-manager .ext-conf {
background-image: url(images/config.png);
}
#file-manager .ext-ini {
.file-manager .ext-ini {
background-image: url(images/config.png);
}
#file-manager .ext-3gp {
.file-manager .ext-3gp {
background-image: url(images/film.png);
}
#file-manager .ext-afp {
.file-manager .ext-afp {
background-image: url(images/code.png);
}
#file-manager .ext-afpa {
.file-manager .ext-afpa {
background-image: url(images/code.png);
}
#file-manager .ext-asp {
.file-manager .ext-asp {
background-image: url(images/code.png);
}
#file-manager .ext-aspx {
.file-manager .ext-aspx {
background-image: url(images/code.png);
}
#file-manager .ext-avi {
.file-manager .ext-avi {
background-image: url(images/film.png);
}
#file-manager .ext-bat {
.file-manager .ext-bat {
background-image: url(images/application.png);
}
#file-manager .ext-bmp {
.file-manager .ext-bmp {
background-image: url(images/picture.png);
}
#file-manager .ext-c {
.file-manager .ext-c {
background-image: url(images/code.png);
}
#file-manager .ext-cfm {
.file-manager .ext-cfm {
background-image: url(images/code.png);
}
#file-manager .ext-cgi {
.file-manager .ext-cgi {
background-image: url(images/code.png);
}
#file-manager .ext-com {
.file-manager .ext-com {
background-image: url(images/application.png);
}
#file-manager .ext-cpp {
.file-manager .ext-cpp {
background-image: url(images/code.png);
}
#file-manager .ext-css {
.file-manager .ext-css {
background-image: url(images/css.png);
}
#file-manager .ext-doc {
.file-manager .ext-doc {
background-image: url(images/doc.png);
}
#file-manager .ext-exe {
.file-manager .ext-exe {
background-image: url(images/application.png);
}
#file-manager .ext-gif {
.file-manager .ext-gif {
background-image: url(images/picture.png);
}
#file-manager .ext-fla {
.file-manager .ext-fla {
background-image: url(images/flash.png);
}
#file-manager .ext-h {
.file-manager .ext-h {
background-image: url(images/code.png);
}
#file-manager .ext-htm {
.file-manager .ext-htm {
background-image: url(images/html.png);
}
#file-manager .ext-html {
.file-manager .ext-html {
background-image: url(images/html.png);
}
#file-manager .ext-jar {
.file-manager .ext-jar {
background-image: url(images/java.png);
}
#file-manager .ext-jpg {
.file-manager .ext-jpg {
background-image: url(images/picture.png);
}
#file-manager .ext-jpeg {
.file-manager .ext-jpeg {
background-image: url(images/picture.png);
}
#file-manager .ext-js {
.file-manager .ext-js {
background-image: url(images/script.png);
}
#file-manager .ext-json {
.file-manager .ext-json {
background-image: url(images/script.png);
}
#file-manager .ext-lasso {
.file-manager .ext-lasso {
background-image: url(images/code.png);
}
#file-manager .ext-log {
.file-manager .ext-log {
background-image: url(images/text-plain.png);
}
#file-manager .ext-m4p {
.file-manager .ext-m4p {
background-image: url(images/music.png);
}
#file-manager .ext-mov {
.file-manager .ext-mov {
background-image: url(images/film.png);
}
#file-manager .ext-mp3 {
.file-manager .ext-mp3 {
background-image: url(images/music.png);
}
#file-manager .ext-mp4 {
.file-manager .ext-mp4 {
background-image: url(images/film.png);
}
#file-manager .ext-mpg {
.file-manager .ext-mpg {
background-image: url(images/film.png);
}
#file-manager .ext-mpeg {
.file-manager .ext-mpeg {
background-image: url(images/film.png);
}
#file-manager .ext-ogg {
.file-manager .ext-ogg {
background-image: url(images/music.png);
}
#file-manager .ext-pcx {
.file-manager .ext-pcx {
background-image: url(images/picture.png);
}
#file-manager .ext-pdf {
.file-manager .ext-pdf {
background-image: url(images/pdf.png);
}
#file-manager .ext-php {
.file-manager .ext-php {
background-image: url(images/php.png);
}
#file-manager .ext-png {
.file-manager .ext-png {
background-image: url(images/picture.png);
}
#file-manager .ext-ppt {
.file-manager .ext-ppt {
background-image: url(images/ppt.png);
}
#file-manager .ext-psd {
.file-manager .ext-psd {
background-image: url(images/psd.png);
}
#file-manager .ext-pl {
.file-manager .ext-pl {
background-image: url(images/script.png);
}
#file-manager .ext-py {
.file-manager .ext-py {
background-image: url(images/script.png);
}
#file-manager .ext-rb {
.file-manager .ext-rb {
background-image: url(images/ruby.png);
}
#file-manager .ext-rbx {
.file-manager .ext-rbx {
background-image: url(images/ruby.png);
}
#file-manager .ext-rhtml {
.file-manager .ext-rhtml {
background-image: url(images/ruby.png);
}
#file-manager .ext-rpm {
.file-manager .ext-rpm {
background-image: url(images/linux.png);
}
#file-manager .ext-ruby {
.file-manager .ext-ruby {
background-image: url(images/ruby.png);
}
#file-manager .ext-sql {
.file-manager .ext-sql {
background-image: url(images/db.png);
}
#file-manager .ext-swf {
.file-manager .ext-swf {
background-image: url(images/flash.png);
}
#file-manager .ext-tif {
.file-manager .ext-tif {
background-image: url(images/picture.png);
}
#file-manager .ext-tiff {
.file-manager .ext-tiff {
background-image: url(images/picture.png);
}
#file-manager .ext-txt {
.file-manager .ext-txt {
background-image: url(images/file.png);
}
#file-manager .ext-vb {
.file-manager .ext-vb {
background-image: url(images/code.png);
}
#file-manager .ext-wav {
.file-manager .ext-wav {
background-image: url(images/music.png);
}
#file-manager .ext-wmv {
.file-manager .ext-wmv {
background-image: url(images/film.png);
}
#file-manager .ext-xls {
.file-manager .ext-xls {
background-image: url(images/xls.png);
}
#file-manager .ext-xml {
.file-manager .ext-xml {
background-image: url(images/code.png);
}
#file-manager .ext-zip {
.file-manager .ext-zip {
background-image: url(images/zip.png);
}
#file-manager .loading {
.file-manager .loading {
background-image: url(images/spinner.gif);
}
.file-manager .drag_start {
background-color: #333;
/*border-radius: 10px;*/
}
.file-manager .drag_over {
background-color: #4a4a4a;
border-radius: 10px;
}

View file

@ -20,7 +20,7 @@
background-color: #999;
}
::-webkit-scrollbar-thumb:horizontal {i
::-webkit-scrollbar-thumb:horizontal {
width: 5px;
background-color: #666;
-webkit-border-radius: 3px;
@ -467,6 +467,100 @@ table [class^="icon-"], [class*=" icon-"] {
background-image: -webkit-gradient(linear,left top,left bottom,color-stop(0.29, rgb(120,120,120)),color-stop(0.77, rgb(77,77,77)));
cursor: row-resize;
}
#uploads-button {
bottom: 4px;
color: #999;
font-size: 12px;
position: absolute;
right: 100px;
z-index: 2;
}
.uploads-container {
background: #1a1a1a;
bottom: 25px;
display: none;
height: 50%;
overflow-y: auto;
position: absolute;
right: 100px;
width: 250px;
z-index: 2;
}
.uploads-container .project-list-title {
position: unset;
margin-bottom: 5px;
}
.uploads-content {
height: 100%;
text-align: center;
width: 100%;
}
.upload-container {
display: inline-block;
height: auto;
width: 95%;
}
.upload-title {
display: inline-block;
max-width: 75%;
width: 80%;
}
.upload-progress-text {
display: inline-block;
width: 20%;
}
.upload-progress {
width: 75%;
margin: 10px auto;
height: 20px;
border: 1px solid #666;
background: #262626;
border-radius: 5px;
overflow: hidden;
}
.upload-progress .bar {
width: 0;
height: 20px;
background-image: url( filemanager/images/progress_bar.png );
}
.upload-dismiss {
display: inline-block;
left: -45px;
max-width: 75%;
position: relative;
text-decoration: underline;
width: auto;
}
.upload-cancel {
color: red;
display: inline-block;
position: relative;
right: -45px;
width: auto;
}
#cursor-position {
position: absolute;
right: 30px;
@ -609,6 +703,7 @@ table [class^="icon-"], [class*=" icon-"] {
left: 0;
right: 10px;
bottom: 276px;
background-color: #1a1a1a;
}
.sb-left-projects {
@ -816,6 +911,7 @@ table [class^="icon-"], [class*=" icon-"] {
background: url(loading.gif) no-repeat center;
}
/* Download iFrame */
#download {
display: none;
@ -829,3 +925,29 @@ table [class^="icon-"], [class*=" icon-"] {
vertical-align: middle;
width: 25px;
}
.drop-overlay {
display: none;
border: 2px dashed #fff;
border-radius: 10px;
background: rgba( 255, 255, 255, 0.15 );
height: 100%;
left: 0;
position: absolute;
top: 0;
width: 100%;
z-index: 97;
}
.drop-overlay-message {
text-align: center;
position: relative;
float: left;
top: 50%;
left: 50%;
transform: translate( -50%, -50% );
}