RaspiStream/var/www/ide/components/project/class.project.php
2017-05-19 12:09:07 +02:00

278 lines
10 KiB
PHP
Executable File

<?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');
class Project extends Common {
//////////////////////////////////////////////////////////////////
// PROPERTIES
//////////////////////////////////////////////////////////////////
public $name = '';
public $path = '';
public $gitrepo = false;
public $gitbranch = '';
public $projects = '';
public $no_return = false;
public $assigned = false;
public $command_exec = '';
//////////////////////////////////////////////////////////////////
// METHODS
//////////////////////////////////////////////////////////////////
// -----------------------------||----------------------------- //
//////////////////////////////////////////////////////////////////
// Construct
//////////////////////////////////////////////////////////////////
public function __construct(){
$this->projects = getJSON('projects.php');
if(file_exists(BASE_PATH . "/data/" . $_SESSION['user'] . '_acl.php')){
$this->assigned = getJSON($_SESSION['user'] . '_acl.php');
}
}
//////////////////////////////////////////////////////////////////
// Get First (Default, none selected)
//////////////////////////////////////////////////////////////////
public function GetFirst(){
$projects_assigned = false;
if($this->assigned){
foreach($this->projects as $project=>$data){
if(in_array($data['path'],$this->assigned)){
$this->name = $data['name'];
$this->path = $data['path'];
break;
}
}
}else{
$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",array("name"=>$this->name,"path"=>$this->path));
}
}
//////////////////////////////////////////////////////////////////
// Get Name From Path
//////////////////////////////////////////////////////////////////
public function GetName(){
foreach($this->projects as $project=>$data){
if($data['path']==$this->path){
$this->name = $data['name'];
}
}
return $this->name;
}
//////////////////////////////////////////////////////////////////
// Open Project
//////////////////////////////////////////////////////////////////
public function Open(){
$pass = false;
foreach($this->projects as $project=>$data){
if($data['path']==$this->path){
$pass = true;
$this->name = $data['name'];
$_SESSION['project'] = $data['path'];
}
}
if($pass){
echo formatJSEND("success",array("name"=>$this->name,"path"=>$this->path));
}else{
echo formatJSEND("error","Error Opening Project");
}
}
//////////////////////////////////////////////////////////////////
// Create
//////////////////////////////////////////////////////////////////
public function Create(){
if($this->name != '' && $this->path != '') {
$this->path = $this->cleanPath();
$this->name = htmlspecialchars($this->name);
if(!$this->isAbsPath($this->path)) {
$this->path = $this->SanitizePath();
}
if($this->path != '') {
$pass = $this->checkDuplicate();
if($pass){
if(!$this->isAbsPath($this->path)) {
mkdir(WORKSPACE . '/' . $this->path);
} else {
if(defined('WHITEPATHS')) {
$allowed = false;
foreach (explode(",",WHITEPATHS) as $whitepath) {
if(strpos($this->path, $whitepath) === 0) {
$allowed = true;
}
}
if(!$allowed) {
die(formatJSEND("error","Absolute Path Only Allowed for ".WHITEPATHS));
}
}
if(!file_exists($this->path)) {
if(!mkdir($this->path.'/', 0755, true)) {
die(formatJSEND("error","Unable to create Absolute Path"));
}
} else {
if(!is_writable($this->path) || !is_readable($this->path)) {
die(formatJSEND("error","No Read/Write Permission"));
}
}
}
$this->projects[] = array("name"=>$this->name,"path"=>$this->path);
saveJSON('projects.php',$this->projects);
// Pull from Git Repo?
if($this->gitrepo && filter_var($this->gitrepo, FILTER_VALIDATE_URL) !== false){
$this->git_branch = $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");
}
} else {
echo formatJSEND("error","Project Name/Folder is empty");
}
}
//////////////////////////////////////////////////////////////////
// Sanitize GitBranch
//////////////////////////////////////////////////////////////////
public function SanitizeGitBranch(){
$sanitized = str_replace(array("..",chr(40), chr(177),"~","^",":","?","*","[","@{","\\"),array(""),$this->git_branch);
return $sanitized;
}
//////////////////////////////////////////////////////////////////
// Rename
//////////////////////////////////////////////////////////////////
public function Rename(){
$revised_array = array();
foreach($this->projects as $project=>$data){
if($data['path']!=$this->path){
$revised_array[] = array("name"=>$data['name'],"path"=>$data['path']);
}
}
$revised_array[] = $this->projects[] = array("name"=>$_GET['project_name'],"path"=>$this->path);
// Save array back to JSON
saveJSON('projects.php',$revised_array);
// Response
echo formatJSEND("success",null);
}
//////////////////////////////////////////////////////////////////
// Delete Project
//////////////////////////////////////////////////////////////////
public function Delete(){
$revised_array = array();
foreach($this->projects as $project=>$data){
if($data['path']!=$this->path){
$revised_array[] = array("name"=>$data['name'],"path"=>$data['path']);
}
}
// Save array back to JSON
saveJSON('projects.php',$revised_array);
// Response
echo formatJSEND("success",null);
}
//////////////////////////////////////////////////////////////////
// Check Duplicate
//////////////////////////////////////////////////////////////////
public function CheckDuplicate(){
$pass = true;
foreach($this->projects as $project=>$data){
if($data['name']==$this->name || $data['path']==$this->path){
$pass = false;
}
}
return $pass;
}
//////////////////////////////////////////////////////////////////
// Sanitize Path
//////////////////////////////////////////////////////////////////
public function SanitizePath(){
$sanitized = str_replace(" ","_",$this->path);
return preg_replace('/[^\w-]/', '', $sanitized);
}
//////////////////////////////////////////////////////////////////
// Clean Path
//////////////////////////////////////////////////////////////////
function cleanPath(){
// prevent Poison Null Byte injections
$path = str_replace(chr(0), '', $this->path );
// prevent go out of the workspace
while (strpos($path , '../') !== false)
$path = str_replace( '../', '', $path );
return $path;
}
//////////////////////////////////////////////////////////////////
// Execute Command
//////////////////////////////////////////////////////////////////
public function ExecuteCMD(){
if(function_exists('system')){
ob_start();
system($this->command_exec);
ob_end_clean();
}
//passthru
else if(function_exists('passthru')){
ob_start();
passthru($this->command_exec);
ob_end_clean();
}
//exec
else if(function_exists('exec')){
exec($this->command_exec , $this->output);
}
//shell_exec
else if(function_exists('shell_exec')){
shell_exec($this->command_exec);
}
}
}