diff options
Diffstat (limited to 'OAuth/src/Lib/OAuthUtil.php')
-rw-r--r-- | OAuth/src/Lib/OAuthUtil.php | 209 |
1 files changed, 209 insertions, 0 deletions
diff --git a/OAuth/src/Lib/OAuthUtil.php b/OAuth/src/Lib/OAuthUtil.php new file mode 100644 index 00000000..8dca8c06 --- /dev/null +++ b/OAuth/src/Lib/OAuthUtil.php @@ -0,0 +1,209 @@ +<?php +// vim: foldmethod=marker +/** + * The MIT License + * + * Copyright (c) 2007 Andy Smith + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files ( the "Software" ), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +namespace MediaWiki\Extensions\OAuth\Lib; + +use MediaWiki\Logger\LoggerFactory; + +class OAuthUtil { + public static function urlencode_rfc3986( $input ) { + if ( is_array( $input ) ) { + return array_map( + array( + self::class, + 'urlencode_rfc3986' + ), + $input + ); + } else { + if ( is_scalar( $input ) ) { + return str_replace( + '+', + ' ', + str_replace( '%7E', '~', rawurlencode( $input ) ) + ); + } else { + return ''; + } + } + } + + + // This decode function isn't taking into consideration the above + // modifications to the encoding process. However, this method doesn't + // seem to be used anywhere so leaving it as is. + public static function urldecode_rfc3986( $string ) { + return urldecode( $string ); + } + + // Utility function for turning the Authorization: header into + // parameters, has to do some unescaping + // Can filter out any non-oauth parameters if needed ( default behaviour ) + // May 28th, 2010 - method updated to tjerk.meesters for a speed improvement. + // see http://code.google.com/p/oauth/issues/detail?id = 163 + public static function split_header( $header, $only_allow_oauth_parameters = true ) { + $logger = LoggerFactory::getInstance( 'OAuth' ); + $logger->debug( __METHOD__ . ": pulling headers from '$header'" ); + $params = array(); + if ( preg_match_all( + '/(' . ( $only_allow_oauth_parameters ? 'oauth_' : '' ) . '[a-z_-]*)=(:?"([^"]*)"|([^,]*))/', + $header, + $matches + ) + ) { + foreach ( $matches[1] as $i => $h ) { + $params[$h] = OAuthUtil::urldecode_rfc3986( + empty( $matches[3][$i] ) ? $matches[4][$i] : $matches[3][$i] + ); + } + if ( isset( $params['realm'] ) ) { + unset( $params['realm'] ); + } + } + + return $params; + } + + // helper to try to sort out headers for people who aren't running apache + public static function get_headers() { + if ( function_exists( 'apache_request_headers' ) ) { + // we need this to get the actual Authorization: header + // because apache tends to tell us it doesn't exist + $headers = apache_request_headers(); + + // sanitize the output of apache_request_headers because + // we always want the keys to be Cased-Like-This and arh() + // returns the headers in the same case as they are in the + // request + $out = array(); + foreach ( $headers as $key => $value ) { + $key = str_replace( + " ", + "-", + ucwords( strtolower( str_replace( "-", " ", $key ) ) ) + ); + $out[$key] = $value; + } + } else { + // otherwise we don't have apache and are just going to have to hope + // that $_SERVER actually contains what we need + $out = array(); + if ( isset( $_SERVER['CONTENT_TYPE'] ) ) { + $out['Content-Type'] = $_SERVER['CONTENT_TYPE']; + } + if ( isset( $_ENV['CONTENT_TYPE'] ) ) { + $out['Content-Type'] = $_ENV['CONTENT_TYPE']; + } + + foreach ( $_SERVER as $key => $value ) { + if ( substr( $key, 0, 5 ) == "HTTP_" ) { + // this is chaos, basically it is just there to capitalize the first + // letter of every word that is not an initial HTTP and strip HTTP + // code from przemek + $key = str_replace( + " ", + "-", + ucwords( strtolower( str_replace( "_", " ", substr( $key, 5 ) ) ) ) + ); + $out[$key] = $value; + } + } + } + + return $out; + } + + // This function takes a input like a=b&a=c&d=e and returns the parsed + // parameters like this + // array( 'a' => array( 'b','c' ), 'd' => 'e' ) + public static function parse_parameters( $input ) { + if ( !isset( $input ) || !$input ) { + return array(); + } + + $pairs = explode( '&', $input ); + + $parsed_parameters = array(); + foreach ( $pairs as $pair ) { + $split = explode( '=', $pair, 2 ); + $parameter = OAuthUtil::urldecode_rfc3986( $split[0] ); + $value = isset( $split[1] ) ? OAuthUtil::urldecode_rfc3986( $split[1] ) : ''; + + if ( isset( $parsed_parameters[$parameter] ) ) { + // We have already recieved parameter( s ) with this name, so add to the list + // of parameters with this name + + if ( is_scalar( $parsed_parameters[$parameter] ) ) { + // This is the first duplicate, so transform scalar ( string ) into an array + // so we can add the duplicates + $parsed_parameters[$parameter] = array( $parsed_parameters[$parameter] ); + } + + $parsed_parameters[$parameter][] = $value; + } else { + $parsed_parameters[$parameter] = $value; + } + } + + return $parsed_parameters; + } + + public static function build_http_query( $params ) { + LoggerFactory::getInstance( 'OAuth' )->debug( + __METHOD__ . " called with params:\n" . print_r( $params, true ) + ); + if ( !$params ) { + return ''; + } + + // Urlencode both keys and values + $keys = OAuthUtil::urlencode_rfc3986( array_keys( $params ) ); + $values = OAuthUtil::urlencode_rfc3986( array_values( $params ) ); + $params = array_combine( $keys, $values ); + + // Parameters are sorted by name, using lexicographical byte value ordering. + // Ref: Spec: 9.1.1 ( 1 ) + uksort( $params, 'strcmp' ); + + $pairs = array(); + foreach ( $params as $parameter => $value ) { + if ( is_array( $value ) ) { + // If two or more parameters share the same name, they are sorted by their value + // Ref: Spec: 9.1.1 ( 1 ) + // June 12th, 2010 - changed to sort because of issue 164 by hidetaka + sort( $value, SORT_STRING ); + foreach ( $value as $duplicate_value ) { + $pairs[] = $parameter . '=' . $duplicate_value; + } + } else { + $pairs[] = $parameter . '=' . $value; + } + } + // For each parameter, the name is separated from the corresponding value by an ' = ' character ( ASCII code 61 ) + // Each name-value pair is separated by an '&' character ( ASCII code 38 ) + return implode( '&', $pairs ); + } +} |