Index: trunk/phase3/docs/hooks.txt |
— | — | @@ -1220,6 +1220,17 @@ |
1221 | 1221 | - wrap String Wrap the message in html (usually something like "<div ...>$1</div>"). |
1222 | 1222 | - flags Integer display flags (NO_ACTION_LINK,NO_EXTRA_USER_LINKS) |
1223 | 1223 | |
| 1224 | +'LoggableUserIPData': called when IP data for a user action can be logged by extensions like CheckUser. |
| 1225 | +This is intended for when users do things that do not already create edits or log entries. |
| 1226 | +$context: The context the of the action, which includes the user and request |
| 1227 | +$data: Associative array of data for handlers to record. It must include values for: |
| 1228 | + - 'namespace' Integer namespace for target title (NS_SPECIAL is allowed) |
| 1229 | + - 'title' Database key string for target title (empty string if not applicable) |
| 1230 | + - 'pageid' Integer page ID for target title (zero if not applicable) |
| 1231 | + - 'action' Wikitext string in the same format as an edit summary |
| 1232 | + - 'comment' Wikitext string in the same format as an edit summary |
| 1233 | + - 'timestamp' Timestamp when the action occured |
| 1234 | + |
1224 | 1235 | 'LoginAuthenticateAudit': a login attempt either succeeded or |
1225 | 1236 | failed. This may be called before the User object is populated, so a |
1226 | 1237 | user object equivalent to an anonymous user. No return data is |
Index: trunk/extensions/CheckUser/CheckUser_body.php |
— | — | @@ -1176,13 +1176,12 @@ |
1177 | 1177 | */ |
1178 | 1178 | protected function getLinksFromRow( $row ) { |
1179 | 1179 | // Log items (old format) and events to logs |
1180 | | - |
1181 | 1180 | if ( $row->cuc_type == RC_LOG && $row->cuc_namespace == NS_SPECIAL ) { |
1182 | 1181 | list( $specialName, $logtype ) = SpecialPage::resolveAliasWithSubpage( $row->cuc_title ); |
1183 | 1182 | $logname = LogPage::logName( $logtype ); |
1184 | 1183 | $title = Title::makeTitle( $row->cuc_namespace, $row->cuc_title ); |
1185 | 1184 | $links = '(' . $this->sk->makeKnownLinkObj( $title, $logname ) . ')'; |
1186 | | - // Log items |
| 1185 | + // Log items (newer format) |
1187 | 1186 | } elseif ( $row->cuc_type == RC_LOG ) { |
1188 | 1187 | $title = Title::makeTitle( $row->cuc_namespace, $row->cuc_title ); |
1189 | 1188 | $links = '(' . $this->sk->makeKnownLinkObj( SpecialPage::getTitleFor( 'Log' ), $this->message['log'], |
Index: trunk/extensions/CheckUser/CheckUser.hooks.php |
— | — | @@ -209,6 +209,52 @@ |
210 | 210 | } |
211 | 211 | |
212 | 212 | /** |
| 213 | + * Handler for non-standard (edit/log) entries that need IP data |
| 214 | + * |
| 215 | + * @param $context IContextSource |
| 216 | + * @param $data Array |
| 217 | + * @return bool |
| 218 | + */ |
| 219 | + protected static function onLoggableUserIPData( IContextSource $context, array $data ) { |
| 220 | + $user = $context->getUser(); |
| 221 | + $request = $context->getRequest(); |
| 222 | + |
| 223 | + // Get IP address |
| 224 | + $ip = $request->getIP(); |
| 225 | + // Get XFF header |
| 226 | + $xff = $request->getHeader( 'X-Forwarded-For' ); |
| 227 | + list( $xff_ip, $isSquidOnly ) = self::getClientIPfromXFF( $xff ); |
| 228 | + // Get agent |
| 229 | + $agent = $request->getHeader( 'User-Agent' ); |
| 230 | + |
| 231 | + $dbw = wfGetDB( DB_MASTER ); |
| 232 | + $cuc_id = $dbw->nextSequenceValue( 'cu_changes_cu_id_seq' ); |
| 233 | + $rcRow = array( |
| 234 | + 'cuc_id' => $cuc_id, |
| 235 | + 'cuc_page_id' => $data['pageid'], // may be 0 |
| 236 | + 'cuc_namespace' => $data['namespace'], |
| 237 | + 'cuc_title' => $data['title'], // may be '' |
| 238 | + 'cuc_minor' => 0, |
| 239 | + 'cuc_user' => $user->getId(), |
| 240 | + 'cuc_user_text' => $user->getName(), |
| 241 | + 'cuc_actiontext' => $data['action'], |
| 242 | + 'cuc_comment' => $data['comment'], |
| 243 | + 'cuc_this_oldid' => 0, |
| 244 | + 'cuc_last_oldid' => 0, |
| 245 | + 'cuc_type' => RC_LOG, |
| 246 | + 'cuc_timestamp' => $dbw->timestamp( $data['timestamp'] ), |
| 247 | + 'cuc_ip' => IP::sanitizeIP( $ip ), |
| 248 | + 'cuc_ip_hex' => $ip ? IP::toHex( $ip ) : null, |
| 249 | + 'cuc_xff' => !$isSquidOnly ? $xff : '', |
| 250 | + 'cuc_xff_hex' => ( $xff_ip && !$isSquidOnly ) ? IP::toHex( $xff_ip ) : null, |
| 251 | + 'cuc_agent' => $agent |
| 252 | + ); |
| 253 | + $dbw->insert( 'cu_changes', $rcRow, __METHOD__ ); |
| 254 | + |
| 255 | + return true; |
| 256 | + } |
| 257 | + |
| 258 | + /** |
213 | 259 | * Hook function to prune data from the cu_changes table |
214 | 260 | */ |
215 | 261 | public static function maybePruneIPData() { |
Index: trunk/extensions/CheckUser/CheckUser.php |
— | — | @@ -63,6 +63,7 @@ |
64 | 64 | $wgHooks['User::mailPasswordInternal'][] = 'CheckUserHooks::updateCUPasswordResetData'; |
65 | 65 | $wgHooks['AuthPluginAutoCreate'][] = 'CheckUserHooks::onAuthPluginAutoCreate'; |
66 | 66 | $wgHooks['AddNewAccount'][] = 'CheckUserHooks::onAddNewAccount'; |
| 67 | +$wgHooks['LoggableUserIPData'][] = 'CheckUserHooks::onLoggableUserIPData'; |
67 | 68 | |
68 | 69 | # Occasional pruning of CU data |
69 | 70 | $wgHooks['ArticleEditUpdatesDeleteFromRecentchanges'][] = 'CheckUserHooks::maybePruneIPData'; |