summaryrefslogtreecommitdiffstats
path: root/management-interface/lib/web
diff options
context:
space:
mode:
authorNils Schwabe2014-06-04 14:27:03 +0200
committerNils Schwabe2014-06-04 14:27:03 +0200
commit155cf6aeea9ba7ecbc39face6442d3ce1b03ad8e (patch)
tree1dcc8354eaf6ce216461fc434d9c1a6a67559914 /management-interface/lib/web
parentImprove login (diff)
downloadmasterserver-155cf6aeea9ba7ecbc39face6442d3ce1b03ad8e.tar.gz
masterserver-155cf6aeea9ba7ecbc39face6442d3ce1b03ad8e.tar.xz
masterserver-155cf6aeea9ba7ecbc39face6442d3ce1b03ad8e.zip
Add webinterface with functionallity
Diffstat (limited to 'management-interface/lib/web')
-rw-r--r--management-interface/lib/web/geo.php101
-rw-r--r--management-interface/lib/web/google/staticmap.php58
-rw-r--r--management-interface/lib/web/openid.php237
-rw-r--r--management-interface/lib/web/pingback.php170
4 files changed, 566 insertions, 0 deletions
diff --git a/management-interface/lib/web/geo.php b/management-interface/lib/web/geo.php
new file mode 100644
index 0000000..c1b915e
--- /dev/null
+++ b/management-interface/lib/web/geo.php
@@ -0,0 +1,101 @@
+<?php
+
+/*
+ Copyright (c) 2009-2014 F3::Factory/Bong Cosca, All rights reserved.
+
+ This file is part of the Fat-Free Framework (http://fatfree.sf.net).
+
+ THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF
+ ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+ Please see the license.txt file for more information.
+*/
+
+namespace Web;
+
+//! Geo plug-in
+class Geo extends \Prefab {
+
+ /**
+ * Return information about specified Unix time zone
+ * @return array
+ * @param $zone string
+ **/
+ function tzinfo($zone) {
+ $ref=new \DateTimeZone($zone);
+ $loc=$ref->getLocation();
+ $trn=$ref->getTransitions($now=time(),$now);
+ $out=array(
+ 'offset'=>$ref->
+ getOffset(new \DateTime('now',new \DateTimeZone('GMT')))/3600,
+ 'country'=>$loc['country_code'],
+ 'latitude'=>$loc['latitude'],
+ 'longitude'=>$loc['longitude'],
+ 'dst'=>$trn[0]['isdst']
+ );
+ unset($ref);
+ return $out;
+ }
+
+ /**
+ * Return geolocation data based on specified/auto-detected IP address
+ * @return array|FALSE
+ * @param $ip string
+ **/
+ function location($ip=NULL) {
+ $fw=\Base::instance();
+ $web=\Web::instance();
+ if (!$ip)
+ $ip=$fw->get('IP');
+ $public=filter_var($ip,FILTER_VALIDATE_IP,
+ FILTER_FLAG_IPV4|FILTER_FLAG_IPV6|
+ FILTER_FLAG_NO_RES_RANGE|FILTER_FLAG_NO_PRIV_RANGE);
+ if (function_exists('geoip_db_avail') &&
+ geoip_db_avail(GEOIP_CITY_EDITION_REV1) &&
+ $out=@geoip_record_by_name($ip)) {
+ $out['request']=$ip;
+ $out['region_code']=$out['region'];
+ $out['region_name']=geoip_region_name_by_code(
+ $out['country_code'],$out['region']);
+ unset($out['country_code3'],$out['region'],$out['postal_code']);
+ return $out;
+ }
+ if (($req=$web->request('http://www.geoplugin.net/json.gp'.
+ ($public?('?ip='.$ip):''))) &&
+ $data=json_decode($req['body'],TRUE)) {
+ $out=array();
+ foreach ($data as $key=>$val)
+ if (!strpos($key,'currency') && $key!=='geoplugin_status'
+ && $key!=='geoplugin_region')
+ $out[$fw->snakecase(substr($key, 10))]=$val;
+ return $out;
+ }
+ return FALSE;
+ }
+
+ /**
+ * Return weather data based on specified latitude/longitude
+ * @return array|FALSE
+ * @param $latitude float
+ * @param $longitude float
+ **/
+ function weather($latitude,$longitude) {
+ $fw=\Base::instance();
+ $web=\Web::instance();
+ $query=array(
+ 'lat'=>$latitude,
+ 'lng'=>$longitude,
+ 'username'=>$fw->hash($fw->get('IP'))
+ );
+ return ($req=$web->request(
+ 'http://ws.geonames.org/findNearByWeatherJSON?'.
+ http_build_query($query))) &&
+ ($data=json_decode($req['body'],TRUE)) &&
+ isset($data['weatherObservation'])?
+ $data['weatherObservation']:
+ FALSE;
+ }
+
+}
diff --git a/management-interface/lib/web/google/staticmap.php b/management-interface/lib/web/google/staticmap.php
new file mode 100644
index 0000000..8d8a5fc
--- /dev/null
+++ b/management-interface/lib/web/google/staticmap.php
@@ -0,0 +1,58 @@
+<?php
+
+/*
+ Copyright (c) 2009-2014 F3::Factory/Bong Cosca, All rights reserved.
+
+ This file is part of the Fat-Free Framework (http://fatfree.sf.net).
+
+ THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF
+ ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+ Please see the license.txt file for more information.
+*/
+
+namespace Web\Google;
+
+//! Google Static Maps API v2 plug-in
+class StaticMap {
+
+ const
+ //! API URL
+ URL_Static='http://maps.googleapis.com/maps/api/staticmap';
+
+ protected
+ //! Query arguments
+ $query=array();
+
+ /**
+ * Specify API key-value pair via magic call
+ * @return object
+ * @param $func string
+ * @param $args array
+ **/
+ function __call($func,array $args) {
+ $this->query[]=array($func,$args[0]);
+ return $this;
+ }
+
+ /**
+ * Generate map
+ * @return string
+ **/
+ function dump() {
+ $fw=\Base::instance();
+ $web=\Web::instance();
+ $out='';
+ return ($req=$web->request(
+ self::URL_Static.'?'.array_reduce(
+ $this->query,
+ function($out,$item) {
+ return ($out.=($out?'&':'').
+ urlencode($item[0]).'='.urlencode($item[1]));
+ }
+ ))) && $req['body']?$req['body']:FALSE;
+ }
+
+}
diff --git a/management-interface/lib/web/openid.php b/management-interface/lib/web/openid.php
new file mode 100644
index 0000000..61ce575
--- /dev/null
+++ b/management-interface/lib/web/openid.php
@@ -0,0 +1,237 @@
+<?php
+
+/*
+ Copyright (c) 2009-2014 F3::Factory/Bong Cosca, All rights reserved.
+
+ This file is part of the Fat-Free Framework (http://fatfree.sf.net).
+
+ THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF
+ ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+ Please see the license.txt file for more information.
+*/
+
+namespace Web;
+
+//! OpenID consumer
+class OpenID extends \Magic {
+
+ protected
+ //! OpenID provider endpoint URL
+ $url,
+ //! HTTP request parameters
+ $args=array();
+
+ /**
+ * Determine OpenID provider
+ * @return string|FALSE
+ * @param $proxy string
+ **/
+ protected function discover($proxy) {
+ // Normalize
+ if (!preg_match('/https?:\/\//i',$this->args['identity']))
+ $this->args['identity']='http://'.$this->args['identity'];
+ $url=parse_url($this->args['identity']);
+ // Remove fragment; reconnect parts
+ $this->args['identity']=$url['scheme'].'://'.
+ (isset($url['user'])?
+ ($url['user'].
+ (isset($url['pass'])?(':'.$url['pass']):'').'@'):'').
+ strtolower($url['host']).(isset($url['path'])?$url['path']:'/').
+ (isset($url['query'])?('?'.$url['query']):'');
+ // HTML-based discovery of OpenID provider
+ $req=\Web::instance()->
+ request($this->args['identity'],array('proxy'=>$proxy));
+ if (!$req)
+ return FALSE;
+ $type=array_values(preg_grep('/Content-Type:/',$req['headers']));
+ if ($type &&
+ preg_match('/application\/xrds\+xml|text\/xml/',$type[0]) &&
+ ($sxml=simplexml_load_string($req['body'])) &&
+ ($xrds=json_decode(json_encode($sxml),TRUE)) &&
+ isset($xrds['XRD'])) {
+ // XRDS document
+ $svc=$xrds['XRD']['Service'];
+ if (isset($svc[0]))
+ $svc=$svc[0];
+ if (preg_grep('/http:\/\/specs\.openid\.net\/auth\/2.0\/'.
+ '(?:server|signon)/',$svc['Type'])) {
+ $this->args['provider']=$svc['URI'];
+ if (isset($svc['LocalID']))
+ $this->args['localidentity']=$svc['LocalID'];
+ elseif (isset($svc['CanonicalID']))
+ $this->args['localidentity']=$svc['CanonicalID'];
+ }
+ $this->args['server']=$svc['URI'];
+ if (isset($svc['Delegate']))
+ $this->args['delegate']=$svc['Delegate'];
+ }
+ else {
+ $len=strlen($req['body']);
+ $ptr=0;
+ // Parse document
+ while ($ptr<$len)
+ if (preg_match(
+ '/^<link\b((?:\h+\w+\h*=\h*'.
+ '(?:"(?:.+?)"|\'(?:.+?)\'))*)\h*\/?>/is',
+ substr($req['body'],$ptr),$parts)) {
+ if ($parts[1] &&
+ // Process attributes
+ preg_match_all('/\b(rel|href)\h*=\h*'.
+ '(?:"(.+?)"|\'(.+?)\')/s',$parts[1],$attr,
+ PREG_SET_ORDER)) {
+ $node=array();
+ foreach ($attr as $kv)
+ $node[$kv[1]]=isset($kv[2])?$kv[2]:$kv[3];
+ if (isset($node['rel']) &&
+ preg_match('/openid2?\.(\w+)/',
+ $node['rel'],$var) &&
+ isset($node['href']))
+ $this->args[$var[1]]=$node['href'];
+
+ }
+ $ptr+=strlen($parts[0]);
+ }
+ else
+ $ptr++;
+ }
+ // Get OpenID provider's endpoint URL
+ if (isset($this->args['provider'])) {
+ // OpenID 2.0
+ $this->args['ns']='http://specs.openid.net/auth/2.0';
+ if (isset($this->args['localidentity']))
+ $this->args['identity']=$this->args['localidentity'];
+ if (isset($this->args['trust_root']))
+ $this->args['realm']=$this->args['trust_root'];
+ }
+ elseif (isset($this->args['server'])) {
+ // OpenID 1.1
+ $this->args['ns']='http://openid.net/signon/1.1';
+ if (isset($this->args['delegate']))
+ $this->args['identity']=$this->args['delegate'];
+ }
+ if (isset($this->args['provider'])) {
+ // OpenID 2.0
+ if (empty($this->args['claimed_id']))
+ $this->args['claimed_id']=$this->args['identity'];
+ return $this->args['provider'];
+ }
+ elseif (isset($this->args['server']))
+ // OpenID 1.1
+ return $this->args['server'];
+ else
+ return FALSE;
+ }
+
+ /**
+ * Initiate OpenID authentication sequence; Return FALSE on failure
+ * or redirect to OpenID provider URL
+ * @return bool
+ * @param $proxy string
+ * @param $attr array
+ * @param $reqd string|array
+ **/
+ function auth($proxy=NULL,$attr=array(),array $reqd=NULL) {
+ $fw=\Base::instance();
+ $root=$fw->get('SCHEME').'://'.$fw->get('HOST');
+ if (empty($this->args['trust_root']))
+ $this->args['trust_root']=$root.$fw->get('BASE').'/';
+ if (empty($this->args['return_to']))
+ $this->args['return_to']=$root.$_SERVER['REQUEST_URI'];
+ $this->args['mode']='checkid_setup';
+ if ($this->url=$this->discover($proxy)) {
+ if ($attr) {
+ $this->args['ns.ax']='http://openid.net/srv/ax/1.0';
+ $this->args['ax.mode']='fetch_request';
+ foreach ($attr as $key=>$val)
+ $this->args['ax.type.'.$key]=$val;
+ $this->args['ax.required']=is_string($reqd)?
+ $reqd:implode(',',$reqd);
+ }
+ $var=array();
+ foreach ($this->args as $key=>$val)
+ $var['openid.'.$key]=$val;
+ $fw->reroute($this->url.'?'.http_build_query($var));
+ }
+ return FALSE;
+ }
+
+ /**
+ * Return TRUE if OpenID verification was successful
+ * @return bool
+ * @param $proxy string
+ **/
+ function verified($proxy=NULL) {
+ preg_match_all('/(?<=^|&)openid\.([^=]+)=([^&]+)/',
+ $_SERVER['QUERY_STRING'],$matches,PREG_SET_ORDER);
+ foreach ($matches as $match)
+ $this->args[$match[1]]=urldecode($match[2]);
+ if (isset($this->args['mode']) &&
+ $this->args['mode']!='error' &&
+ $this->url=$this->discover($proxy)) {
+ $this->args['mode']='check_authentication';
+ $var=array();
+ foreach ($this->args as $key=>$val)
+ $var['openid.'.$key]=$val;
+ $req=\Web::instance()->request(
+ $this->url,
+ array(
+ 'method'=>'POST',
+ 'content'=>http_build_query($var),
+ 'proxy'=>$proxy
+ )
+ );
+ return (bool)preg_match('/is_valid:true/i',$req['body']);
+ }
+ return FALSE;
+ }
+
+ /**
+ * Return OpenID response fields
+ * @return array
+ **/
+ function response() {
+ return $this->args;
+ }
+
+ /**
+ * Return TRUE if OpenID request parameter exists
+ * @return bool
+ * @param $key string
+ **/
+ function exists($key) {
+ return isset($this->args[$key]);
+ }
+
+ /**
+ * Bind value to OpenID request parameter
+ * @return string
+ * @param $key string
+ * @param $val string
+ **/
+ function set($key,$val) {
+ return $this->args[$key]=$val;
+ }
+
+ /**
+ * Return value of OpenID request parameter
+ * @return mixed
+ * @param $key string
+ **/
+ function get($key) {
+ return isset($this->args[$key])?$this->args[$key]:NULL;
+ }
+
+ /**
+ * Remove OpenID request parameter
+ * @return NULL
+ * @param $key
+ **/
+ function clear($key) {
+ unset($this->args[$key]);
+ }
+
+}
+
diff --git a/management-interface/lib/web/pingback.php b/management-interface/lib/web/pingback.php
new file mode 100644
index 0000000..897ed67
--- /dev/null
+++ b/management-interface/lib/web/pingback.php
@@ -0,0 +1,170 @@
+<?php
+
+/*
+ Copyright (c) 2009-2014 F3::Factory/Bong Cosca, All rights reserved.
+
+ This file is part of the Fat-Free Framework (http://fatfree.sf.net).
+
+ THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF
+ ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+ Please see the license.txt file for more information.
+*/
+
+namespace Web;
+
+//! Pingback 1.0 protocol (client and server) implementation
+class Pingback extends \Prefab {
+
+ protected
+ //! Transaction history
+ $log;
+
+ /**
+ * Return TRUE if URL points to a pingback-enabled resource
+ * @return bool
+ * @param $url
+ **/
+ protected function enabled($url) {
+ $web=\Web::instance();
+ $req=$web->request($url);
+ $found=FALSE;
+ if ($req && $req['body']) {
+ // Look for pingback header
+ foreach ($req['headers'] as $header)
+ if (preg_match('/^X-Pingback:\h*(.+)/',$header,$href)) {
+ $found=$href[1];
+ break;
+ }
+ if (!$found &&
+ // Scan page for pingback link tag
+ preg_match('/<link\h+(.+?)\h*\/?>/i',$req['body'],$parts) &&
+ preg_match('/rel\h*=\h*"pingback"/i',$parts[1]) &&
+ preg_match('/href\h*=\h*"\h*(.+?)\h*"/i',$parts[1],$href))
+ $found=$href[1];
+ }
+ return $found;
+ }
+
+ /**
+ * Load local page contents, parse HTML anchor tags, find permalinks,
+ * and send XML-RPC calls to corresponding pingback servers
+ * @return NULL
+ * @param $source string
+ **/
+ function inspect($source) {
+ $fw=\Base::instance();
+ $web=\Web::instance();
+ $parts=parse_url($source);
+ if (empty($parts['scheme']) || empty($parts['host']) ||
+ $parts['host']==$fw->get('HOST')) {
+ $req=$web->request($source);
+ $doc=new \DOMDocument('1.0',$fw->get('ENCODING'));
+ $doc->stricterrorchecking=FALSE;
+ $doc->recover=TRUE;
+ if ($req && @$doc->loadhtml($req['body'])) {
+ // Parse anchor tags
+ $links=$doc->getelementsbytagname('a');
+ foreach ($links as $link) {
+ $permalink=$link->getattribute('href');
+ // Find pingback-enabled resources
+ if ($permalink && $found=$this->enabled($permalink)) {
+ $req=$web->request($found,
+ array(
+ 'method'=>'POST',
+ 'header'=>'Content-Type: application/xml',
+ 'content'=>xmlrpc_encode_request(
+ 'pingback.ping',
+ array($source,$permalink),
+ array('encoding'=>$fw->get('ENCODING'))
+ )
+ )
+ );
+ if ($req && $req['body'])
+ $this->log.=date('r').' '.
+ $permalink.' [permalink:'.$found.']'.PHP_EOL.
+ $req['body'].PHP_EOL;
+ }
+ }
+ }
+ unset($doc);
+ }
+ }
+
+ /**
+ * Receive ping, check if local page is pingback-enabled, verify
+ * source contents, and return XML-RPC response
+ * @return string
+ * @param $func callback
+ * @param $path string
+ **/
+ function listen($func,$path=NULL) {
+ $fw=\Base::instance();
+ if (PHP_SAPI!='cli') {
+ header('X-Powered-By: '.$fw->get('PACKAGE'));
+ header('Content-Type: application/xml; '.
+ 'charset='.$charset=$fw->get('ENCODING'));
+ }
+ if (!$path)
+ $path=$fw->get('BASE');
+ $web=\Web::instance();
+ $args=xmlrpc_decode_request($fw->get('BODY'),$method,$charset);
+ $options=array('encoding'=>$charset);
+ if ($method=='pingback.ping' && isset($args[0],$args[1])) {
+ list($source,$permalink)=$args;
+ $doc=new \DOMDocument('1.0',$fw->get('ENCODING'));
+ // Check local page if pingback-enabled
+ $parts=parse_url($permalink);
+ if ((empty($parts['scheme']) ||
+ $parts['host']==$fw->get('HOST')) &&
+ preg_match('/^'.preg_quote($path,'/').'/'.
+ ($fw->get('CASELESS')?'i':''),$parts['path']) &&
+ $this->enabled($permalink)) {
+ // Check source
+ $parts=parse_url($source);
+ if ((empty($parts['scheme']) ||
+ $parts['host']==$fw->get('HOST')) &&
+ ($req=$web->request($source)) &&
+ $doc->loadhtml($req['body'])) {
+ $links=$doc->getelementsbytagname('a');
+ foreach ($links as $link) {
+ if ($link->getattribute('href')==$permalink) {
+ call_user_func_array($func,
+ array($source,$req['body']));
+ // Success
+ die(xmlrpc_encode_request(NULL,$source,$options));
+ }
+ }
+ // No link to local page
+ die(xmlrpc_encode_request(NULL,0x11,$options));
+ }
+ // Source failure
+ die(xmlrpc_encode_request(NULL,0x10,$options));
+ }
+ // Doesn't exist (or not pingback-enabled)
+ die(xmlrpc_encode_request(NULL,0x21,$options));
+ }
+ // Access denied
+ die(xmlrpc_encode_request(NULL,0x31,$options));
+ }
+
+ /**
+ * Return transaction history
+ * @return string
+ **/
+ function log() {
+ return $this->log;
+ }
+
+ /**
+ * Instantiate class
+ * @return object
+ **/
+ function __construct() {
+ // Suppress errors caused by invalid HTML structures
+ libxml_use_internal_errors(TRUE);
+ }
+
+}