r109562 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r109561‎ | r109562 | r109563 >
Date:19:16, 19 January 2012
Author:reedy
Status:reverted (Comments)
Tags:
Comment:
* (bug 32341) Add upload by URL domain limitation.
Modified paths:
  • /trunk/phase3/RELEASE-NOTES-1.19 (modified) (history)
  • /trunk/phase3/includes/DefaultSettings.php (modified) (history)
  • /trunk/phase3/includes/HttpFunctions.php (modified) (history)
  • /trunk/phase3/includes/api/ApiBase.php (modified) (history)
  • /trunk/phase3/includes/api/ApiUpload.php (modified) (history)
  • /trunk/phase3/includes/specials/SpecialUpload.php (modified) (history)
  • /trunk/phase3/includes/upload/UploadFromUrl.php (modified) (history)
  • /trunk/phase3/languages/messages/MessagesEn.php (modified) (history)

Diff [purge]

Index: trunk/phase3/RELEASE-NOTES-1.19
@@ -120,6 +120,7 @@
121121 * (bug 29309) allow CSS class per tooltip (tipsy)
122122 * (bug 33565) Add accesskey/tooltip to submit buttons on Special:EditWatchlist.
123123 * (bug 17959) Inline rendering/thumbnailing for Gimp XCF images
 124+* (bug 32341) Add upload by URL domain limitation.
124125
125126 === Bug fixes in 1.19 ===
126127 * $wgUploadNavigationUrl should be used for file redlinks if.
Index: trunk/phase3/includes/upload/UploadFromUrl.php
@@ -38,6 +38,27 @@
3939 }
4040
4141 /**
 42+ * Checks whether the URL is for an allowed host
 43+ *
 44+ * @param $url string
 45+ * @return bool
 46+ */
 47+ public static function isAllowedHost( $url ) {
 48+ global $wgCopyUploadsDomains;
 49+ if ( !count( $wgCopyUploadsDomains ) ) {
 50+ return true;
 51+ }
 52+ $valid = false;
 53+ foreach( $wgCopyUploadsDomains as $domain ) {
 54+ if ( strpos( $url, $domain ) !== false ) {
 55+ $valid = true;
 56+ break;
 57+ }
 58+ }
 59+ return $valid;
 60+ }
 61+
 62+ /**
4263 * Entry point for API upload
4364 *
4465 * @param $name string
@@ -66,8 +87,9 @@
6788 */
6889 public function initializeFromRequest( &$request ) {
6990 $desiredDestName = $request->getText( 'wpDestFile' );
70 - if ( !$desiredDestName )
 91+ if ( !$desiredDestName ) {
7192 $desiredDestName = $request->getText( 'wpUploadFileURL' );
 93+ }
7294 return $this->initialize(
7395 $desiredDestName,
7496 trim( $request->getVal( 'wpUploadFileURL' ) ),
@@ -101,6 +123,9 @@
102124 return Status::newFatal( 'http-invalid-url' );
103125 }
104126
 127+ if( !self::isAllowedHost( $this->mUrl ) ) {
 128+ return Status::newFatal( 'upload-copy-upload-invalid-domain' );
 129+ }
105130 if ( !$this->mAsync ) {
106131 return $this->reallyFetchFile();
107132 }
@@ -219,9 +244,7 @@
220245 if ( $this->mAsync ) {
221246 $sessionKey = $this->insertJob( $comment, $pageText, $watch, $user );
222247
223 - $status = new Status;
224 - $status->error( 'async', $sessionKey );
225 - return $status;
 248+ return Status::newFatal( 'async', $sessionKey );
226249 }
227250
228251 return parent::performUpload( $comment, $pageText, $watch, $user );
Index: trunk/phase3/includes/api/ApiBase.php
@@ -1231,6 +1231,7 @@
12321232 'nouploadmodule' => array( 'code' => 'nouploadmodule', 'info' => 'No upload module set' ),
12331233 'uploaddisabled' => array( 'code' => 'uploaddisabled', 'info' => 'Uploads are not enabled. Make sure $wgEnableUploads is set to true in LocalSettings.php and the PHP ini setting file_uploads is true' ),
12341234 'copyuploaddisabled' => array( 'code' => 'copyuploaddisabled', 'info' => 'Uploads by URL is not enabled. Make sure $wgAllowCopyUploads is set to true in LocalSettings.php.' ),
 1235+ 'copyuploadbaddomain' => array( 'code' => 'copyuploadbaddomain', 'info' => 'Uploads by URL are not allowed from this domain.' ),
12351236
12361237 'filename-tooshort' => array( 'code' => 'filename-tooshort', 'info' => 'The filename is too short' ),
12371238 'filename-toolong' => array( 'code' => 'filename-toolong', 'info' => 'The filename is too long' ),
Index: trunk/phase3/includes/api/ApiUpload.php
@@ -318,6 +318,10 @@
319319 $this->dieUsageMsg( 'copyuploaddisabled' );
320320 }
321321
 322+ if ( !UploadFromUrl::isAllowedHost( $this->mParams['url'] ) ) {
 323+ $this->dieUsageMsg( 'copyuploadbaddomain' );
 324+ }
 325+
322326 $async = false;
323327 if ( $this->mParams['asyncdownload'] ) {
324328 $this->checkAsyncDownloadEnabled();
@@ -336,7 +340,6 @@
337341 $this->mUpload = new UploadFromUrl;
338342 $this->mUpload->initialize( $this->mParams['filename'],
339343 $this->mParams['url'], $async );
340 -
341344 }
342345
343346 return true;
Index: trunk/phase3/includes/DefaultSettings.php
@@ -451,6 +451,10 @@
452452 * This feature is experimental and broken as of r81612.
453453 */
454454 $wgAllowAsyncCopyUploads = false;
 455+/**
 456+ * A list of domains copy uploads can come from
 457+ */
 458+$wgCopyUploadsDomains = array();
455459
456460 /**
457461 * Max size for uploads, in bytes. If not set to an array, applies to all
Index: trunk/phase3/includes/HttpFunctions.php
@@ -233,7 +233,7 @@
234234 * Generate a new request object
235235 * @param $url String: url to use
236236 * @param $options Array: (optional) extra params to pass (see Http::request())
237 - * @return \CurlHttpRequest|\PhpHttpRequest
 237+ * @return CurlHttpRequest|PhpHttpRequest
238238 * @see MWHttpRequest::__construct
239239 */
240240 public static function factory( $url, $options = null ) {
Index: trunk/phase3/includes/specials/SpecialUpload.php
@@ -177,8 +177,7 @@
178178 if (
179179 $this->mTokenOk && !$this->mCancelUpload &&
180180 ( $this->mUpload && $this->mUploadClicked )
181 - )
182 - {
 181+ ) {
183182 $this->processUpload();
184183 } else {
185184 # Backwards compatibility hook
@@ -186,8 +185,6 @@
187186 wfDebug( "Hook 'UploadForm:initial' broke output of the upload form" );
188187 return;
189188 }
190 -
191 -
192189 $this->showUploadForm( $this->getUploadForm() );
193190 }
194191
@@ -821,7 +818,7 @@
822819 );
823820 }
824821
825 - $canUploadByUrl = UploadFromUrl::isEnabled() && $this->getUser()->isAllowed( 'upload_by_url' );
 822+ $canUploadByUrl = UploadFromUrl::isEnabled() && UploadFromUrl::isAllowed( $this->getUser() );
826823 $radio = $canUploadByUrl;
827824 $selectedSourceType = strtolower( $this->getRequest()->getText( 'wpSourceType', 'File' ) );
828825
Index: trunk/phase3/languages/messages/MessagesEn.php
@@ -2235,6 +2235,7 @@
22362236 'upload-too-many-redirects' => 'The URL contained too many redirects',
22372237 'upload-unknown-size' => 'Unknown size',
22382238 'upload-http-error' => 'An HTTP error occured: $1',
 2239+'upload-copy-upload-invalid-domain' => 'Copy uploads are not available from this domain.',
22392240
22402241 # File backend
22412242 'backend-fail-stream' => 'Could not stream file $1.',

Follow-up revisions

RevisionCommit summaryAuthorDate
r109564Followup r109562...reedy20:26, 19 January 2012
r109570r109562: Register new message key for maintenance scriptraymond21:12, 19 January 2012
r109741Revert feature out of r109562, r109564, r109570...reedy17:33, 22 January 2012
r111120* (bug 32341) Add upload by URL domain limitation....reedy23:22, 9 February 2012

Comments

#Comment by Platonides (talk | contribs)   19:31, 19 January 2012

strpos() on the full url? Really? That won't really work.

Plus, I'd add a hook there, for extensions which may want to perform further checks (eg. flickr domain is allowed, and the extension additionally checks that the license is free).

#Comment by Reedy (talk | contribs)   19:38, 19 January 2012

Well, yes, if you then do something fancy like putting it in some other part, you can fool it. But for the Wikipedia use case, that won't work anyway

How should it be done? Unless we include protocols in the listed urls, and then check if it's at the start of the string? Or go to the extent of extracting the host from the given url (do we have a nice way in MW to do this? Feels like it'd be re-inventing the wheel)... And then becomes protocol irrelevant...

We currently have in WikiMap, and is similarily basic...

	/**
	 * @return string
	 * @throws MWException
	 */
	public function getHostname() {
		$prefixes = array( '[http://', http://',] '[https://' https://'] );
		foreach ( $prefixes as $prefix ) {
			if ( substr( $this->mCanonicalServer, 0, strlen( $prefix ) ) ) {
				return substr( $this->mCanonicalServer, strlen( $prefix ) );
			}
		}
		throw new MWException( "Invalid hostname for wiki {$this->mMinor}.{$this->mMajor}" );
	}

The hook is an extension to this, so isn't a major issue to be done now

#Comment by Reedy (talk | contribs)   20:22, 19 January 2012

Oh, wfParseUrl()

#Comment by Krinkle (talk | contribs)   00:56, 22 January 2012
-		$canUploadByUrl = UploadFromUrl::isEnabled() && $this->getUser()->isAllowed( 'upload_by_url' );
+		$canUploadByUrl = UploadFromUrl::isEnabled() && UploadFromUrl::isAllowed( $this->getUser() );

User::isAllowed doesn't appear to be called any more. This wasn't intentional?

#Comment by Reedy (talk | contribs)   01:19, 22 January 2012

Yup, reduces code duplication with what's in UploadFromUrl::isAllowed(), and also does the parent functions to check the user has upload rights

#Comment by Krinkle (talk | contribs)   01:58, 22 January 2012

Aha, UploadFromUrl::isAllowed() already existed before this commit and contains the call to User::isAllowed(). I confused it with the added method "isAllowedHost()", but that's not being called here. Thanks :)

#Comment by Siebrand (talk | contribs)   12:23, 22 January 2012

This is a feature that should not be added during a slush. Please revert.

#Comment by Reedy (talk | contribs)   13:43, 22 January 2012

The reason for doing so, as this is a requisite for the enabling of a long requested feature for commons, allowing upload by URL from other WMF projects.

The code is somewhat standalone, and if nothing is set, it's not going to change anything; it is also easy enough to test

I'd rather this actually got into 1.19, rather than reverting it out, hanging onto a patch for a while, putting into trunk/1.19 then merging to 1.19wmf1. If I had had the time available prior to have done this, I would have

#Comment by Siebrand (talk | contribs)   13:49, 22 January 2012

I understand, but you're increasing review workload, and we have agreed we would not do that. Please take it out. If you are allowed to add features, there is no reason to disallow or disencourage others to do it.

#Comment by Reedy (talk | contribs)   14:01, 22 January 2012

Mmm... Is it worth leaving the message in?

#Comment by Siebrand (talk | contribs)   13:50, 22 January 2012

Btw, I think the slush is already taking too long, over two weeks now. I'm looking forward to ending it and getting it over with!

#Comment by Reedy (talk | contribs)   14:00, 22 January 2012

Haha. Now that's something I agree with!

Status & tagging log