r42427 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r42426‎ | r42427 | r42428 >
Date:22:53, 23 October 2008
Author:tparscal
Status:old (Comments)
Tags:
Comment:
Added a token to the drafts table which prevents operations from being performed more than once.
Modified paths:
  • /trunk/extensions/Drafts/Drafts.classes.php (modified) (history)
  • /trunk/extensions/Drafts/Drafts.hooks.php (modified) (history)
  • /trunk/extensions/Drafts/Drafts.sql (modified) (history)

Diff [purge]

Index: trunk/extensions/Drafts/Drafts.sql
@@ -1,5 +1,6 @@
22 create table /*$wgDBPrefix*/drafts (
33 draft_id INTEGER AUTO_INCREMENT PRIMARY KEY,
 4+ draft_token INTEGER,
45 draft_user INTEGER,
56 draft_namespace INTEGER,
67 draft_title VARBINARY(255),
Index: trunk/extensions/Drafts/Drafts.classes.php
@@ -10,6 +10,7 @@
1111 private $_db;
1212 private $_exists = false;
1313 private $_id;
 14+ private $_token;
1415 private $_userID;
1516 private $_title;
1617 private $_section;
@@ -65,6 +66,7 @@
6667 }
6768
6869 // Synchronize data
 70+ $this->_token = $row['draft_token'];
6971 $this->_title = Title::makeTitle( $row['draft_namespace'], $row['draft_title'] );
7072 $this->_section = $row['draft_section'];
7173 $this->_starttime = $row['draft_starttime'];
@@ -82,13 +84,14 @@
8385 }
8486
8587 public function save() {
86 - global $wgUser;
 88+ global $wgUser, $wgRequest;
8789
8890 // Get db connection
8991 $this->getDB();
9092
9193 // Build data
9294 $data = array(
 95+ 'draft_token' => (int) $this->getToken(),
9396 'draft_user' => (int) $wgUser->getID(),
9497 'draft_namespace' => (int) $this->_title->getNamespace(),
9598 'draft_title' => (string) $this->_title->getDBKey(),
@@ -112,13 +115,26 @@
113116 ),
114117 __METHOD__
115118 );
 119+ } else {
 120+ // Before creating a new draft record, lets check if we have already
 121+ $token = $wgRequest->getIntOrNull( 'wpDraftToken' );
 122+ if( $token !== null) {
 123+ // Check if token has been used already for this article
 124+ if( $this->_db->selectField( 'drafts', 'draft_token',
 125+ array(
 126+ 'draft_namespace' => $data['draft_namespace'],
 127+ 'draft_title' => $data['draft_title'],
 128+ 'draft_user' => $data['draft_user'],
 129+ ),
 130+ __METHOD__
 131+ ) === false ) {
 132+ $this->_db->insert( 'drafts', $data, __METHOD__ );
 133+ $this->_id = $this->_db->insertId();
 134+ // Update state
 135+ $this->_exists = true;
 136+ }
 137+ }
116138 }
117 - else {
118 - $this->_db->insert( 'drafts', $data, __METHOD__ );
119 - $this->_id = $this->_db->insertId();
120 - // Update state
121 - $this->_exists = true;
122 - }
123139
124140 // Return success
125141 return true;
@@ -148,6 +164,7 @@
149165
150166 public static function newFromRow( $row ) {
151167 $draft = new Draft( $row['draft_id'], false);
 168+ $draft->setToken( $row['draft_token'] );
152169 $draft->setTitle( Title::makeTitle( $row['draft_namespace'], $row['draft_title'] ) );
153170 $draft->setSection( $row['draft_section'] );
154171 $draft->setStartTime( $row['draft_starttime'] );
@@ -339,7 +356,7 @@
340357 Xml::element( 'a',
341358 array(
342359 'href' => $urlDiscard,
343 - 'onclick' => htmlspecialchars( "if( !wgAjaxSaveDraft.insync ) return confirm('" . Xml::escapeJsString( wfMsgHTML( 'drafts-view-warn' ) ) . "')" )
 360+ 'onclick' => "if( !wgAjaxSaveDraft.insync ) return confirm('" . Xml::escapeJsString( wfMsgHTML( 'drafts-view-warn' ) ) . "')"
344361 ),
345362 wfMsg( 'drafts-view-discard' )
346363 )
@@ -355,6 +372,10 @@
356373 return 0;
357374 }
358375
 376+ public static function newToken() {
 377+ return time();
 378+ }
 379+
359380 private function getDB() {
360381 // Get database connection if we don't already have one
361382 if ( $this->_db === null ) {
@@ -375,6 +396,13 @@
376397 return $this->_id;
377398 }
378399
 400+ public function setToken( $token ) {
 401+ $this->_token = $token;
 402+ }
 403+ public function getToken() {
 404+ return $this->_token;
 405+ }
 406+
379407 public function getUserID( $userID ) {
380408 $this->_userID = $userID;
381409 }
Index: trunk/extensions/Drafts/Drafts.hooks.php
@@ -164,6 +164,13 @@
165165 $buttons['savedraft'] .= Xml::element( 'input',
166166 array(
167167 'type' => 'hidden',
 168+ 'name' => 'wpDraftToken',
 169+ 'value' => Draft::newToken()
 170+ )
 171+ );
 172+ $buttons['savedraft'] .= Xml::element( 'input',
 173+ array(
 174+ 'type' => 'hidden',
168175 'name' => 'wpDraftID',
169176 'value' => $wgRequest->getInt( 'draft', '' )
170177 )

Comments

#Comment by Brion VIBBER (talk | contribs)   23:45, 23 October 2008

Token needs some more random salt in it -- multiple section edits could be opened legitimately in the same second, but would conflict as currently listed.

Status & tagging log