diff options
author | Nils Schwabe | 2014-06-04 14:27:03 +0200 |
---|---|---|
committer | Nils Schwabe | 2014-06-04 14:27:03 +0200 |
commit | 155cf6aeea9ba7ecbc39face6442d3ce1b03ad8e (patch) | |
tree | 1dcc8354eaf6ce216461fc434d9c1a6a67559914 /management-interface/lib/web | |
parent | Improve login (diff) | |
download | masterserver-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.php | 101 | ||||
-rw-r--r-- | management-interface/lib/web/google/staticmap.php | 58 | ||||
-rw-r--r-- | management-interface/lib/web/openid.php | 237 | ||||
-rw-r--r-- | management-interface/lib/web/pingback.php | 170 |
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); + } + +} |