From 7749b79e2faddfa46fbdc05b689c3bed55c1892f Mon Sep 17 00:00:00 2001 From: Lawrence Date: Sat, 28 Oct 2017 02:40:30 +0800 Subject: [PATCH] Implemented start of web interface to update Static IP addresses or use DHCP. Currently saves to files in /etc/raspap/networking, still need to build something to generate a working config for dhcpcd --- ajax/networking/get_all_interfaces.php | 4 + ajax/networking/get_int_config.php | 27 ++++++ ajax/networking/get_ip_summary.php | 15 ++++ ajax/networking/save_int_config.php | 75 +++++++++++++++++ includes/functions.php | 2 +- includes/networking.php | 31 +++---- index.php | 14 ++-- installers/common.sh | 8 ++ js/custom.js | 111 +++++++++++++++++++++++++ 9 files changed, 265 insertions(+), 22 deletions(-) create mode 100644 ajax/networking/get_all_interfaces.php create mode 100644 ajax/networking/get_int_config.php create mode 100644 ajax/networking/get_ip_summary.php create mode 100644 ajax/networking/save_int_config.php create mode 100644 js/custom.js diff --git a/ajax/networking/get_all_interfaces.php b/ajax/networking/get_all_interfaces.php new file mode 100644 index 0000000..432d0a5 --- /dev/null +++ b/ajax/networking/get_all_interfaces.php @@ -0,0 +1,4 @@ + diff --git a/ajax/networking/get_int_config.php b/ajax/networking/get_int_config.php new file mode 100644 index 0000000..f132f45 --- /dev/null +++ b/ajax/networking/get_int_config.php @@ -0,0 +1,27 @@ +1,'output'=>['DHCPConfig'=>$intDHCPConfig,'StaticConfig'=>$intStaticConfig]]; + echo json_encode($jsonData); + +} else { + $jsonData = ['return'=>2,'output'=>['Error getting data']]; + echo json_encode($jsonData); +} + +?> diff --git a/ajax/networking/get_ip_summary.php b/ajax/networking/get_ip_summary.php new file mode 100644 index 0000000..cd42f57 --- /dev/null +++ b/ajax/networking/get_ip_summary.php @@ -0,0 +1,15 @@ +$intResult,'output'=>$intOutput]; + echo json_encode($jsonData); +} else { + $jsonData = ['return'=>2,'output'=>['Error getting data']]; + echo json_encode($jsonData); +} + +?> diff --git a/ajax/networking/save_int_config.php b/ajax/networking/save_int_config.php new file mode 100644 index 0000000..1f69872 --- /dev/null +++ b/ajax/networking/save_int_config.php @@ -0,0 +1,75 @@ + $val) { + if(is_array($val)) { + $res[] = "[$key]"; + foreach($val as $skey => $sval) $res[] = "$skey = ".(is_numeric($sval) ? $sval : '"'.$sval.'"'); + } + else $res[] = "$key = ".(is_numeric($val) ? $val : '"'.$val.'"'); + } + if(safefilerewrite($file, implode("\r\n", $res))) { + return true; + } else { + return false; + } +} + +function safefilerewrite($fileName, $dataToSave) { + if ($fp = fopen($fileName, 'w')) { + $startTime = microtime(TRUE); + do { + $canWrite = flock($fp, LOCK_EX); + // If lock not obtained sleep for 0 - 100 milliseconds, to avoid collision and CPU load + if(!$canWrite) usleep(round(rand(0, 100)*1000)); + } while ((!$canWrite)and((microtime(TRUE)-$startTime) < 5)); + + //file was locked so now we can store information + if ($canWrite) { + fwrite($fp, $dataToSave); + flock($fp, LOCK_UN); + } + fclose($fp); + return true; + } else { + return false; + } +} + + session_start(); + include_once('../../includes/config.php'); + include_once('../../includes/functions.php'); + var_dump($_POST); + if(isset($_POST['interface']) && isset($_POST['csrf_token']) && CSRFValidate()) { + $int = $_POST['interface']; + $cfg = []; + if($_POST[$int.'-static'] == 'true') { + $file = "STATIC-".$int.".ini"; + $ip = $_POST[$int.'-ipaddress']; + $netmask = mask2cidr($_POST[$int.'-netmask']); + $dns1 = $_POST[$int.'-dnssvr']; + $dns2 = $_POST[$int.'-dnssvralt']; + + $cfg['static'] = $_POST[$int.'-static']; + $cfg['interface'] = $int; + $cfg['routers'] = $_POST[$int.'-gateway']; + $cfg['ip_address'] = $ip."/".$netmask; + $cfg['domain_name_server'] = $dns1." ".$dns2; + + if(write_php_ini($cfg,RASPI_CONFIG_NETWORKING.'/'.$file)) { + $jsonData = ['return'=>0,'output'=>['Successfully Updated Network Configuration']]; + } else { + $jsonData = ['return'=>1,'output'=>['Error saving network configuration']]; + } + } + } else { + $jsonData = ['return'=>2,'output'=>['Error saving network configuration']]; + } + echo json_encode($jsonData); +?> diff --git a/includes/functions.php b/includes/functions.php index f391e46..dce7e66 100755 --- a/includes/functions.php +++ b/includes/functions.php @@ -7,7 +7,7 @@ */ function CSRFToken() { ?> - + + CSRFToken(); +?>
@@ -42,30 +43,26 @@ function DisplayNetworkingConfig(){
'.$interface.'
-
- '; - foreach(${$interface} as $line) { - echo $line.'
'; - } - echo ' +
'; } ?> + Refresh
-
+

Adapter IP Address Settings:

-

Enable Fallback to Static Option:

-
@@ -99,6 +96,12 @@ function DisplayNetworkingConfig(){
+
+ + +
+ Save Settings + Apply Settings
diff --git a/index.php b/index.php index 84d6b22..bc74581 100755 --- a/index.php +++ b/index.php @@ -17,16 +17,11 @@ * @link https://github.com/billz/raspap-webgui * @see http://sirlagz.net/2013/02/08/raspap-webgui/ */ - +/* define('RASPI_CONFIG', '/etc/raspap'); +define('RASPI_CONFIG_NETWORKING',RASPI_CONFIG.'/networking'); define('RASPI_ADMIN_DETAILS', RASPI_CONFIG.'/raspap.auth'); -//if(file_exists(RASPI_CONFIG.'/raspap.auth')) { -// define('RASPI_ADMIN_DETAILS', RASPI_CONFIG.'/raspap.auth'); -//} else { -// define('RASPI_ADMIN_DETAILS',''); -//} - // Constants for configuration file paths. // These are typical for default RPi installs. Modify if needed. define('RASPI_DNSMASQ_CONFIG', '/etc/dnsmasq.conf'); @@ -42,7 +37,9 @@ define('RASPI_TORPROXY_CONFIG', '/etc/tor/torrc'); // Optional services, set to true to enable. define('RASPI_OPENVPN_ENABLED', false ); define('RASPI_TORPROXY_ENABLED', false ); +*/ +include_once( 'includes/config.php' ); include_once( RASPI_CONFIG.'/raspap.php' ); include_once( 'includes/functions.php' ); include_once( 'includes/dashboard.php' ); @@ -248,5 +245,8 @@ $theme_url = 'dist/css/' . $theme; + + + diff --git a/installers/common.sh b/installers/common.sh index f1eb700..21dd0ae 100755 --- a/installers/common.sh +++ b/installers/common.sh @@ -84,10 +84,18 @@ function create_raspap_directories() { sudo mv $raspap_dir "$raspap_dir.`date +%F-%R`" || install_error "Unable to move old '$raspap_dir' out of the way" fi sudo mkdir -p "$raspap_dir" || install_error "Unable to create directory '$raspap_dir'" + # Create a directory for existing file backups. sudo mkdir -p "$raspap_dir/backups" + # Create a directory to store networking configs + sudo mkdir -p "$raspap_dir/networking" + # Copy existing dhcpcd.conf to use as base config + cat /etc/dhcpcd.conf > "$raspap_dir/networking/defaults" + sudo chown -R $raspap_user:$raspap_user "$raspap_dir" || install_error "Unable to change file ownership for '$raspap_dir'" + + } # Fetches latest files from github to webroot diff --git a/js/custom.js b/js/custom.js new file mode 100644 index 0000000..8f8b61a --- /dev/null +++ b/js/custom.js @@ -0,0 +1,111 @@ +function createNetmaskAddr(bitCount) { + var mask=[]; + for(i=0;i<4;i++) { + var n = Math.min(bitCount, 8); + mask.push(256 - Math.pow(2, 8-n)); + bitCount -= n; + } + return mask.join('.'); +} + +function loadSummary(strInterface) { + $.post('/ajax/networking/get_ip_summary.php',{interface:strInterface,csrf_token:csrf},function(data){ + jsonData = JSON.parse(data); + console.log(jsonData); + if(jsonData['return'] == 0) { + $('#'+strInterface+'-summary').html(jsonData['output'].join('
')); + } else if(jsonData['return'] == 2) { + $('#'+strInterface+'-summary').append(''); + } + }); +} + +function getAllInterfaces() { + $.get('/ajax/networking/get_all_interfaces.php',function(data){ + jsonData = JSON.parse(data); + $.each(jsonData,function(ind,value){loadSummary(value)}); + }); +} + +function setupTabs() { + $('a[data-toggle="tab"]').on('shown.bs.tab',function(e){ + var target = $(e.target).attr('href'); + if(!target.match('summary')) { + var int = target.replace("#",""); + loadCurrentSettings(int); + } + }); +} + +function loadCurrentSettings(strInterface) { + $.post('/ajax/networking/get_int_config.php',{interface:strInterface,csrf_token:csrf},function(data){ + jsonData = JSON.parse(data); + //console.log(data); + $.each(jsonData['output'],function(i,v) { + //console.log(i); + var int = v['interface']; + //console.log('interface : '+int); + $.each(v,function(i2,v2) { + //console.log(i2+":"+v2); + switch(i2) { + case "static": + if(v2 == 1) { + $('#'+int+'-static').click(); + } + break; + case "interface": + break; + case "ip_address": + var arrIPNetmask = v2.split('/'); + $('#'+int+'-ipaddress').val(arrIPNetmask[0]); + $('#'+int+'-netmask').val(createNetmaskAddr(arrIPNetmask[1])); + break; + case "routers": + $('#'+int+'-gateway').val(v2); + break; + case "domain_name_server": + svrsDNS = v2.split(" "); + $('#'+int+'-dnssvr').val(svrsDNS[0]); + $('#'+int+'-dnssvralt').val(svrsDNS[1]); + break; + } + }); + }); + }); +} + +function setupBtns() { + $('#btnSummaryRefresh').click(function(){getAllInterfaces();}); + $('.intsave').click(function(){ + var int = $(this).data('int'); + var frmInt = $('#frm-'+int).find(':input'); + var arrFormData = {}; + $.each(frmInt,function(i3,v3){ + if($(v3).attr('type') == 'radio') { + arrFormData[$(v3).attr('id')] = $(v3).prop('checked'); + } else { + arrFormData[$(v3).attr('id')] = $(v3).val(); + } + }); + arrFormData['interface'] = int; + arrFormData['csrf_token'] = csrf; + $.post('/ajax/networking/save_int_config.php',arrFormData,function(data){ + console.log(data); + }); + }); +} + +$().ready(function(){ + csrf = $('#csrf_token').val(); + pageCurrent = window.location.href.split("?")[1].split("=")[1]; + pageCurrent = pageCurrent.replace("#",""); + switch(pageCurrent) { + case "network_conf": + getAllInterfaces(); + setupTabs(); + setupBtns(); + break; + } +}); + +