* @file
* @ingroup Upload
*/
+
use MediaWiki\MediaWikiServices;
use MediaWiki\Shell\Shell;
+use MediaWiki\User\UserIdentity;
/**
* @defgroup Upload Upload related
protected $mTempPath;
/** @var TempFSFile|null Wrapper to handle deleting the temp file */
protected $tempFileObj;
-
- protected $mDesiredDestName, $mDestName, $mRemoveTempFile, $mSourceType;
- protected $mTitle = false, $mTitleError = 0;
- protected $mFilteredName, $mFinalExtension;
- protected $mLocalFile, $mStashFile, $mFileSize, $mFileProps;
+ /** @var string|null */
+ protected $mDesiredDestName;
+ /** @var string|null */
+ protected $mDestName;
+ /** @var string|null */
+ protected $mRemoveTempFile;
+ /** @var string|null */
+ protected $mSourceType;
+ /** @var Title|bool */
+ protected $mTitle = false;
+ /** @var int */
+ protected $mTitleError = 0;
+ /** @var string|null */
+ protected $mFilteredName;
+ /** @var string|null */
+ protected $mFinalExtension;
+ /** @var LocalFile */
+ protected $mLocalFile;
+ /** @var UploadStashFile */
+ protected $mStashFile;
+ /** @var int|null */
+ protected $mFileSize;
+ /** @var array|null */
+ protected $mFileProps;
+ /** @var string[] */
protected $mBlackListedExtensions;
- protected $mJavaDetected, $mSVGNSError;
+ /** @var bool|null */
+ protected $mJavaDetected;
+ /** @var string|null */
+ protected $mSVGNSError;
protected static $safeXmlEncodings = [
'UTF-8',
* identifying the missing permission.
* Can be overridden by subclasses.
*
- * @param User $user
+ * @param UserIdentity $user
* @return bool|string
*/
- public static function isAllowed( $user ) {
+ public static function isAllowed( UserIdentity $user ) {
+ $permissionManager = MediaWikiServices::getInstance()->getPermissionManager();
foreach ( [ 'upload', 'edit' ] as $permission ) {
- if ( !$user->isAllowed( $permission ) ) {
+ if ( !$permissionManager->userHasRight( $user, $permission ) ) {
return $permission;
}
}
return $result;
}
- $error = '';
- if ( !Hooks::run( 'UploadVerification',
- [ $this->mDestName, $this->mTempPath, &$error ], '1.28' )
- ) {
- return [ 'status' => self::HOOK_ABORTED, 'error' => $error ];
- }
-
return [ 'status' => self::OK ];
}
return $warnings;
}
+ /**
+ * Convert the warnings array returned by checkWarnings() to something that
+ * can be serialized. File objects will be converted to an associative array
+ * with the following keys:
+ *
+ * - fileName: The name of the file
+ * - timestamp: The upload timestamp
+ *
+ * @param mixed[] $warnings
+ * @return mixed[]
+ */
+ public static function makeWarningsSerializable( $warnings ) {
+ array_walk_recursive( $warnings, function ( &$param, $key ) {
+ if ( $param instanceof File ) {
+ $param = [
+ 'fileName' => $param->getName(),
+ 'timestamp' => $param->getTimestamp()
+ ];
+ } elseif ( is_object( $param ) ) {
+ throw new InvalidArgumentException(
+ 'UploadBase::makeWarningsSerializable: ' .
+ 'Unexpected object of class ' . get_class( $param ) );
+ }
+ } );
+ return $warnings;
+ }
+
/**
* Check whether the resulting filename is different from the desired one,
* but ignore things like ucfirst() and spaces/underscore things
* @throws UploadStashNotLoggedInException
*/
public function stashFile( User $user = null ) {
+ wfDeprecated( __METHOD__, '1.28' );
+
return $this->doStashFile( $user );
}
return $file;
}
- /**
- * Stash a file in a temporary directory, returning a key which can be used
- * to find the file again. See stashFile().
- *
- * @deprecated since 1.28
- * @return string File key
- */
- public function stashFileGetKey() {
- wfDeprecated( __METHOD__, '1.28' );
- return $this->doStashFile()->getFileKey();
- }
-
- /**
- * alias for stashFileGetKey, for backwards compatibility
- *
- * @deprecated since 1.28
- * @return string File key
- */
- public function stashSession() {
- wfDeprecated( __METHOD__, '1.28' );
- return $this->doStashFile()->getFileKey();
- }
-
/**
* If we've modified the upload file we need to manually remove it
* on exit to clean up.
$enc = null;
}
- if ( $enc ) {
+ if ( $enc !== null ) {
$chunk = iconv( $enc, "ASCII//IGNORE", $chunk );
}
* @todo Replace this with a whitelist filter!
* @param string $element
* @param array $attribs
- * @param array|null $data
+ * @param string|null $data
* @return bool|array
*/
public function checkSvgScriptCallback( $element, $attribs, $data = null ) {
* Check a block of CSS or CSS fragment for anything that looks like
* it is bringing in remote code.
* @param string $value a string of CSS
- * @param bool $propOnly only check css properties (start regex with :)
* @return bool true if the CSS contains an illegal string, false if otherwise
*/
private static function checkCssFragment( $value ) {
* wfFindFile finds a file, it exists in a shared repository.
*/
$file = wfFindFile( $this->getTitle(), [ 'latest' => true ] );
- if ( $file && !$user->isAllowed( 'reupload-shared' ) ) {
+ if ( $file && !MediaWikiServices::getInstance()
+ ->getPermissionManager()
+ ->userHasRight( $user, 'reupload-shared' )
+ ) {
return [ 'fileexists-shared-forbidden', $file->getName() ];
}
* @return bool
*/
public static function userCanReUpload( User $user, File $img ) {
- if ( $user->isAllowed( 'reupload' ) ) {
+ $permissionManager = MediaWikiServices::getInstance()->getPermissionManager();
+ if ( $permissionManager->userHasRight( $user, 'reupload' ) ) {
return true; // non-conditional
- } elseif ( !$user->isAllowed( 'reupload-own' ) ) {
+ } elseif ( !$permissionManager->userHasRight( $user, 'reupload-own' ) ) {
return false;
}
$partname = $n ? substr( $filename, 0, $n ) : $filename;
return (
- substr( $partname, 3, 3 ) == 'px-' ||
- substr( $partname, 2, 3 ) == 'px-'
- ) &&
- preg_match( "/[0-9]{2}/", substr( $partname, 0, 2 ) );
+ substr( $partname, 3, 3 ) == 'px-' ||
+ substr( $partname, 2, 3 ) == 'px-'
+ ) &&
+ preg_match( "/[0-9]{2}/", substr( $partname, 0, 2 ) );
}
/**
* @return Status[]|bool
*/
public static function getSessionStatus( User $user, $statusKey ) {
- $cache = MediaWikiServices::getInstance()->getMainObjectStash();
- $key = $cache->makeKey( 'uploadstatus', $user->getId() ?: md5( $user->getName() ), $statusKey );
+ $store = self::getUploadSessionStore();
+ $key = self::getUploadSessionKey( $store, $user, $statusKey );
- return $cache->get( $key );
+ return $store->get( $key );
}
/**
*
* The value will be set in cache for 1 day
*
+ * Avoid triggering this method on HTTP GET/HEAD requests
+ *
* @param User $user
* @param string $statusKey
* @param array|bool $value
* @return void
*/
public static function setSessionStatus( User $user, $statusKey, $value ) {
- $cache = MediaWikiServices::getInstance()->getMainObjectStash();
- $key = $cache->makeKey( 'uploadstatus', $user->getId() ?: md5( $user->getName() ), $statusKey );
+ $store = self::getUploadSessionStore();
+ $key = self::getUploadSessionKey( $store, $user, $statusKey );
if ( $value === false ) {
- $cache->delete( $key );
+ $store->delete( $key );
} else {
- $cache->set( $key, $value, $cache::TTL_DAY );
+ $store->set( $key, $value, $store::TTL_DAY );
}
}
+
+ /**
+ * @param BagOStuff $store
+ * @param User $user
+ * @param string $statusKey
+ * @return string
+ */
+ private static function getUploadSessionKey( BagOStuff $store, User $user, $statusKey ) {
+ return $store->makeKey(
+ 'uploadstatus',
+ $user->getId() ?: md5( $user->getName() ),
+ $statusKey
+ );
+ }
+
+ /**
+ * @return BagOStuff
+ */
+ private static function getUploadSessionStore() {
+ return ObjectCache::getInstance( 'db-replicated' );
+ }
}