diff -r dc838fd61a06 -r 0437a7cf1acc plugins/admin/UserManager.php --- a/plugins/admin/UserManager.php Thu Dec 20 22:23:07 2007 -0500 +++ b/plugins/admin/UserManager.php Fri Dec 21 18:21:20 2007 -0500 @@ -15,9 +15,12 @@ function page_Admin_UserManager() { global $db, $session, $paths, $template, $plugins; // Common objects + global $lang; if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN ) { - echo '

Error: Not authenticated

It looks like your administration session is invalid or you are not authorized to access this administration page. Please re-authenticate to continue.

'; + $login_link = makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true); + echo '

' . $lang->get('adm_err_not_auth_title') . '

'; + echo '

' . $lang->get('adm_err_not_auth_body', array( 'login_link' => $login_link )) . '

'; return; } @@ -123,7 +126,7 @@ if ( count($errors) < 1 ) { - $q = $db->sql_query('SELECT u.user_level FROM '.table_prefix.'users AS u WHERE u.user_id = ' . $user_id . ';'); + $q = $db->sql_query('SELECT u.user_level, u.user_has_avatar, u.avatar_type FROM '.table_prefix.'users AS u WHERE u.user_id = ' . $user_id . ';'); if ( !$q ) $db->_die(); @@ -134,8 +137,10 @@ $row = $db->fetchrow(); $existing_level =& $row['user_level']; + $avi_type =& $row['avatar_type']; + $has_avi = ( $row['user_has_avatar'] == 1 ); $db->free_result(); - + $to_update_users = array(); if ( $user_id != $session->user_id ) { @@ -161,80 +166,231 @@ $to_update_users['activation_key'] = sha1($session->dss_rand()); } - $to_update_users_extra = array(); - $to_update_users_extra['user_aim'] = $imaddr_aim; - $to_update_users_extra['user_msn'] = $imaddr_msn; - $to_update_users_extra['user_yahoo'] = $imaddr_yahoo; - $to_update_users_extra['user_xmpp'] = $imaddr_xmpp; - $to_update_users_extra['user_homepage'] = $homepage; - $to_update_users_extra['user_location'] = $location; - $to_update_users_extra['user_job'] = $occupation; - $to_update_users_extra['user_hobbies'] = $hobbies; - $to_update_users_extra['email_public'] = ( $email_public ) ? '1' : '0'; - - $update_sql = ''; - - foreach ( $to_update_users as $key => $unused_crap ) + // Avatar validation + $action = ( isset($_POST['avatar_action']) ) ? $_POST['avatar_action'] : 'keep'; + $avi_path = ENANO_ROOT . '/' . getConfig('avatar_directory') . '/' . $user_id . '.' . $avi_type; + switch($action) { - $value =& $to_update_users[$key]; - $value = $db->escape($value); - $update_sql .= ( empty($update_sql) ? '' : ',' ) . "$key='$value'"; - } - - $update_sql = 'UPDATE '.table_prefix."users SET $update_sql WHERE user_id=$user_id;"; - - $update_sql_extra = ''; - - foreach ( $to_update_users_extra as $key => $unused_crap ) - { - $value =& $to_update_users_extra[$key]; - $value = $db->escape($value); - $update_sql_extra .= ( empty($update_sql_extra) ? '' : ',' ) . "$key='$value'"; + case 'keep': + default: + break; + case 'remove': + if ( $has_avi ) + { + // First switch the avatar off + $to_update_users['user_has_avatar'] = '0'; + @unlink($avi_path); + } + break; + case 'set_http': + case 'set_file': + // Hackish way to preserve the UNIX philosophy of reusing as much code as possible + if ( $action == 'set_http' ) + { + // Check if this action is enabled + if ( getConfig('avatar_upload_http') !== '1' ) + { + // non-localized, only appears on hack attempt + $errors[] = 'Uploads over HTTP are disabled.'; + break; + } + // Download the file + require_once( ENANO_ROOT . '/includes/http.php' ); + + if ( !preg_match('/^http:\/\/([a-z0-9-\.]+)(:([0-9]+))?\/(.+)$/', $_POST['avatar_http_url'], $match) ) + { + $errors[] = $lang->get('usercp_avatar_invalid_url'); + break; + } + + $hostname = $match[1]; + $uri = '/' . $match[4]; + $port = ( $match[3] ) ? intval($match[3]) : 80; + $max_size = intval(getConfig('avatar_max_size')); + + // Get temporary file + $tempfile = tempnam(false, "enanoavatar_{$user_id}"); + if ( !$tempfile ) + $errors[] = 'Error getting temp file.'; + + @unlink($tempfile); + $request = new Request_HTTP($hostname, $uri, 'GET', $port); + $result = $request->write_response_to_file($tempfile, 50, $max_size); + if ( !$result || $request->response_code != HTTP_OK ) + { + @unlink($tempfile); + $errors[] = $lang->get('usercp_avatar_bad_write'); + break; + } + + // Response written. Proceed to validation... + } + else + { + // Check if this action is enabled + if ( getConfig('avatar_upload_file') !== '1' ) + { + // non-localized, only appears on hack attempt + $errors[] = 'Uploads from the browser are disabled.'; + break; + } + + $max_size = intval(getConfig('avatar_max_size')); + + $file =& $_FILES['avatar_file']; + $tempfile =& $file['tmp_name']; + if ( filesize($tempfile) > $max_size ) + { + @unlink($tempfile); + $errors[] = $lang->get('usercp_avatar_file_too_large'); + break; + } + } + $file_type = get_image_filetype($tempfile); + if ( !$file_type ) + { + unlink($tempfile); + $errors[] = $lang->get('usercp_avatar_bad_filetype'); + break; + } + + $avi_path_new = ENANO_ROOT . '/' . getConfig('avatar_directory') . '/' . $user_id . '.' . $file_type; + + // The file type is good - validate dimensions and animation + switch($file_type) + { + case 'png': + $is_animated = is_png_animated($tempfile); + $dimensions = png_get_dimensions($tempfile); + break; + case 'gif': + $is_animated = is_gif_animated($tempfile); + $dimensions = gif_get_dimensions($tempfile); + break; + case 'jpg': + $is_animated = false; + $dimensions = jpg_get_dimensions($tempfile); + break; + default: + $errors[] = 'API mismatch'; + break 2; + } + // Did we get invalid size data? If so the image is probably corrupt. + if ( !$dimensions ) + { + @unlink($tempfile); + $errors[] = $lang->get('usercp_avatar_corrupt_image'); + break; + } + // Is the image animated? + if ( $is_animated && getConfig('avatar_enable_anim') !== '1' ) + { + @unlink($tempfile); + $errors[] = $lang->get('usercp_avatar_disallowed_animation'); + break; + } + // Check image dimensions + list($image_x, $image_y) = $dimensions; + $max_x = intval(getConfig('avatar_max_width')); + $max_y = intval(getConfig('avatar_max_height')); + if ( $image_x > $max_x || $image_y > $max_y ) + { + @unlink($tempfile); + $errors[] = $lang->get('usercp_avatar_too_large'); + break; + } + // All good! + @unlink($avi_path); + if ( rename($tempfile, $avi_path_new) ) + { + $to_update_users['user_has_avatar'] = '1'; + $to_update_users['avatar_type'] = $file_type; + } + else + { + // move failed - turn avatar off + $to_update_users['user_has_avatar'] = '0'; + } + break; } - $update_sql_extra = 'UPDATE '.table_prefix."users_extra SET $update_sql_extra WHERE user_id=$user_id;"; - - if ( !$db->sql_query($update_sql) ) - $db->_die(); - - if ( !$db->sql_query($update_sql_extra) ) - $db->_die(); - - if ( $existing_level != $user_level ) + if ( count($errors) < 1 ) { - // We need to update group memberships - if ( $existing_level == USER_LEVEL_ADMIN ) + $to_update_users_extra = array(); + $to_update_users_extra['user_aim'] = $imaddr_aim; + $to_update_users_extra['user_msn'] = $imaddr_msn; + $to_update_users_extra['user_yahoo'] = $imaddr_yahoo; + $to_update_users_extra['user_xmpp'] = $imaddr_xmpp; + $to_update_users_extra['user_homepage'] = $homepage; + $to_update_users_extra['user_location'] = $location; + $to_update_users_extra['user_job'] = $occupation; + $to_update_users_extra['user_hobbies'] = $hobbies; + $to_update_users_extra['email_public'] = ( $email_public ) ? '1' : '0'; + + $update_sql = ''; + + foreach ( $to_update_users as $key => $unused_crap ) { - $q = $db->sql_query('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,edit_summary,author,page_text) VALUES(\'security\',\'u_from_admin\',' . time() . ',"' . $db->escape($_SERVER['REMOTE_ADDR']) . '","' . $db->escape($session->username) . '","' . $db->escape($username) . '");'); - if ( !$q ) - $db->_die(); - $session->remove_user_from_group($user_id, GROUP_ID_ADMIN); + $value =& $to_update_users[$key]; + $value = $db->escape($value); + $update_sql .= ( empty($update_sql) ? '' : ',' ) . "$key='$value'"; } - else if ( $existing_level == USER_LEVEL_MOD ) + + $update_sql = 'UPDATE '.table_prefix."users SET $update_sql WHERE user_id=$user_id;"; + + $update_sql_extra = ''; + + foreach ( $to_update_users_extra as $key => $unused_crap ) { - $q = $db->sql_query('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,edit_summary,author,page_text) VALUES(\'security\',\'u_from_mod\',' . time() . ',"' . $db->escape($_SERVER['REMOTE_ADDR']) . '","' . $db->escape($session->username) . '","' . $db->escape($username) . '");'); - if ( !$q ) - $db->_die(); - $session->remove_user_from_group($user_id, GROUP_ID_MOD); + $value =& $to_update_users_extra[$key]; + $value = $db->escape($value); + $update_sql_extra .= ( empty($update_sql_extra) ? '' : ',' ) . "$key='$value'"; } - if ( $user_level == USER_LEVEL_ADMIN ) - { - $q = $db->sql_query('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,edit_summary,author,page_text) VALUES(\'security\',\'u_to_admin\',' . time() . ',"' . $db->escape($_SERVER['REMOTE_ADDR']) . '","' . $db->escape($session->username) . '","' . $db->escape($username) . '");'); - if ( !$q ) - $db->_die(); - $session->add_user_to_group($user_id, GROUP_ID_ADMIN, false); - } - else if ( $user_level == USER_LEVEL_MOD ) + $update_sql_extra = 'UPDATE '.table_prefix."users_extra SET $update_sql_extra WHERE user_id=$user_id;"; + + if ( !$db->sql_query($update_sql) ) + $db->_die(); + + if ( !$db->sql_query($update_sql_extra) ) + $db->_die(); + + if ( $existing_level != $user_level ) { - $q = $db->sql_query('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,edit_summary,author,page_text) VALUES(\'security\',\'u_to_mod\',' . time() . ',"' . $db->escape($_SERVER['REMOTE_ADDR']) . '","' . $db->escape($session->username) . '","' . $db->escape($username) . '");'); - if ( !$q ) - $db->_die(); - $session->add_user_to_group($user_id, GROUP_ID_MOD, false); + // We need to update group memberships + if ( $existing_level == USER_LEVEL_ADMIN ) + { + $q = $db->sql_query('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,edit_summary,author,page_text) VALUES(\'security\',\'u_from_admin\',' . time() . ',"' . $db->escape($_SERVER['REMOTE_ADDR']) . '","' . $db->escape($session->username) . '","' . $db->escape($username) . '");'); + if ( !$q ) + $db->_die(); + $session->remove_user_from_group($user_id, GROUP_ID_ADMIN); + } + else if ( $existing_level == USER_LEVEL_MOD ) + { + $q = $db->sql_query('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,edit_summary,author,page_text) VALUES(\'security\',\'u_from_mod\',' . time() . ',"' . $db->escape($_SERVER['REMOTE_ADDR']) . '","' . $db->escape($session->username) . '","' . $db->escape($username) . '");'); + if ( !$q ) + $db->_die(); + $session->remove_user_from_group($user_id, GROUP_ID_MOD); + } + + if ( $user_level == USER_LEVEL_ADMIN ) + { + $q = $db->sql_query('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,edit_summary,author,page_text) VALUES(\'security\',\'u_to_admin\',' . time() . ',"' . $db->escape($_SERVER['REMOTE_ADDR']) . '","' . $db->escape($session->username) . '","' . $db->escape($username) . '");'); + if ( !$q ) + $db->_die(); + $session->add_user_to_group($user_id, GROUP_ID_ADMIN, false); + } + else if ( $user_level == USER_LEVEL_MOD ) + { + $q = $db->sql_query('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,edit_summary,author,page_text) VALUES(\'security\',\'u_to_mod\',' . time() . ',"' . $db->escape($_SERVER['REMOTE_ADDR']) . '","' . $db->escape($session->username) . '","' . $db->escape($username) . '");'); + if ( !$q ) + $db->_die(); + $session->add_user_to_group($user_id, GROUP_ID_MOD, false); + } } + + echo '
Your changes have been saved.
'; } - - echo '
Your changes have been saved.
'; } } @@ -290,7 +446,7 @@ echo 'No username provided'; return false; } - $q = $db->sql_query('SELECT u.user_id AS authoritative_uid, u.username, u.email, u.real_name, u.signature, u.account_active, u.user_level, x.* FROM '.table_prefix.'users AS u + $q = $db->sql_query('SELECT u.user_id AS authoritative_uid, u.username, u.email, u.real_name, u.signature, u.account_active, u.user_level, u.user_has_avatar, u.avatar_type, x.* FROM '.table_prefix.'users AS u LEFT JOIN '.table_prefix.'users_extra AS x ON ( u.user_id = x.user_id OR x.user_id IS NULL ) WHERE ( ' . ENANO_SQLFUNC_LOWERCASE . '(u.username) = \'' . $db->escape(strtolower($username)) . '\' OR u.username = \'' . $db->escape($username) . '\' ) AND u.user_id != 1;'); @@ -314,6 +470,8 @@ $form->user_level= $row['user_level']; $form->account_active = ( $row['account_active'] == 1 ); $form->email_public = ( $row['email_public'] == 1 ); + $form->has_avatar = ( $row['user_has_avatar'] == 1 ); + $form->avi_type = $row['avatar_type']; $form->im = array( 'aim' => $row['user_aim'], 'yahoo' => $row['user_yahoo'], @@ -541,6 +699,20 @@ var $email_public = false; /** + * Whether the user has an avatar or not. + * @var bool + */ + + var $has_avatar = false; + + /** + * The type of avatar the user has. One of "jpg", "png", or "gif". + * @var string + */ + + var $avi_type = 'png'; + + /** * Constructor. */ @@ -557,6 +729,7 @@ function render() { global $db, $session, $paths, $template, $plugins; // Common objects + global $lang; if ( file_exists( ENANO_ROOT . "/themes/$template->theme/admin_usermanager_form.tpl" ) ) { $parser = $template->makeParser('admin_usermanager_form.tpl'); @@ -768,6 +941,70 @@ + + + + + {lang:adminusers_avatar_heading} + + + + + + {lang:usercp_avatar_label_current} + + + + {AVATAR_ALT} + + {lang:adminusers_avatar_image_none} + + + + + + + {lang:adminusers_avatar_lbl_change} + + + +
+
+
+ + + + + + + + @@ -895,6 +1132,14 @@ 'FORM_ACTION' => $form_action )); + if ( $this->has_avatar ) + { + $parser->assign_vars(array( + 'AVATAR_SRC' => make_avatar_url($this->user_id, $this->avi_type), + 'AVATAR_ALT' => $lang->get('usercp_avatar_image_alt', array('username' => $this->username)) + )); + } + $parser->assign_bool(array( 'password_meter' => ( getConfig('pw_strength_enable') == '1' ), 'ul_member' => ( $this->user_level == USER_LEVEL_CHPREF ), @@ -902,7 +1147,8 @@ 'ul_admin' => ( $this->user_level == USER_LEVEL_ADMIN ), 'account_active' => ( $this->account_active === true ), 'email_public' => ( $this->email_public === true ), - 'same_user' => ( $this->user_id == $session->user_id ) + 'same_user' => ( $this->user_id == $session->user_id ), + 'user_has_avatar' => ( $this->has_avatar ) )); $parsed = $parser->run();