function linkback_get_target($target) { // Resolve target (https://github.com/converspace/webmention/issues/43) $request = HTTPClient::start(); try { $response = $request->head($target); } catch (Exception $ex) { return NULL; } try { $notice = Notice::fromUri($response->getEffectiveUrl()); } catch (UnknownUriException $ex) { preg_match('/\\/notice\\/(\\d+)(?:#.*)?$/', $response->getEffectiveUrl(), $match); $notice = Notice::getKV('id', $match[1]); } if ($notice instanceof Notice && $notice->isLocal()) { return $notice; } else { $user = User::getKV('uri', $response->getEffectiveUrl()); if (!$user) { preg_match('/\\/user\\/(\\d+)(?:#.*)?$/', $response->getEffectiveUrl(), $match); $user = User::getKV('id', $match[1]); } if (!$user) { preg_match('/\\/([^\\/\\?#]+)(?:#.*)?$/', $response->getEffectiveUrl(), $match); if (linkback_lenient_target_match(common_profile_url($match[1]), $response->getEffectiveUrl())) { $user = User::getKV('nickname', $match[1]); } } if ($user instanceof User) { return $user; } } return NULL; }
function nextUrl() { if ($this->j < count($this->users)) { $nickname = $this->users[$this->j]; $this->j++; return array(common_profile_url($nickname), null, null, '1.0'); } else { return null; } }
/** * We've gotten a post event on the Salmon backchannel, probably a reply. * * @todo validate if we need to handle this post, then call into * ostatus_profile's general incoming-post handling. */ function handlePost() { common_log(LOG_INFO, "Received post of '{$this->activity->objects[0]->id}' from '{$this->activity->actor->id}'"); // @fixme: process all activity objects? switch ($this->activity->objects[0]->type) { case ActivityObject::ARTICLE: case ActivityObject::BLOGENTRY: case ActivityObject::NOTE: case ActivityObject::STATUS: case ActivityObject::COMMENT: break; default: // TRANS: Client exception thrown when an undefied activity is performed. throw new ClientException(_m('Cannot handle that kind of post.')); } // Notice must either be a) in reply to a notice by this user // or b) to the attention of this user // or c) in reply to a notice to the attention of this user $context = $this->activity->context; if (!empty($context->replyToID)) { $notice = Notice::staticGet('uri', $context->replyToID); if (empty($notice)) { // TRANS: Client exception. throw new ClientException(_m('In reply to unknown notice.')); } if ($notice->profile_id != $this->user->id && !in_array($this->user->id, $notice->getReplies())) { // TRANS: Client exception. throw new ClientException(_m('In reply to a notice not by this user and not mentioning this user.')); } } else { if (!empty($context->attention)) { if (!in_array($this->user->uri, $context->attention) && !in_array(common_profile_url($this->user->nickname), $context->attention)) { common_log(LOG_ERR, "{$this->user->uri} not in attention list (" . implode(',', $context->attention) . ")"); // TRANS: Client exception. throw new ClientException(_m('To the attention of user(s), not including this one.')); } } else { // TRANS: Client exception. throw new ClientException(_m('Not to anyone in reply to anything.')); } } $existing = Notice::staticGet('uri', $this->activity->objects[0]->id); if (!empty($existing)) { common_log(LOG_ERR, "Not saving notice '{$existing->uri}'; already exists."); return; } $this->saveNotice(); }
function updateProfileURL($user) { $profile = $user->getProfile(); if (empty($profile)) { throw new Exception("Can't find profile for user {$user->nickname} ({$user->id})"); } $orig = clone $profile; $profile->profileurl = common_profile_url($user->nickname); if (!have_option('q', 'quiet')) { print "Updating profile url for {$user->nickname} ({$user->id}) " . "from {$orig->profileurl} to {$profile->profileurl}..."; } $result = $profile->update($orig); if (!$result) { print "FAIL.\n"; common_log_db_error($profile, 'UPDATE', __FILE__); throw new Exception("Can't update profile for user {$user->nickname} ({$user->id})"); } common_broadcast_profile($profile); print "OK.\n"; }
/** * Handle a post * * Validate input and save changes. Reload the form with a success * or error message. * * @return void */ function handlePost() { // CSRF protection $token = $this->trimmed('token'); if (!$token || $token != common_session_token()) { // TRANS: Form validation error. $this->showForm(_('There was a problem with your session token. ' . 'Try again, please.')); return; } if (Event::handle('StartProfileSaveForm', array($this))) { try { $nickname = Nickname::normalize($this->trimmed('nickname')); } catch (NicknameException $e) { $this->showForm($e->getMessage()); return; } $fullname = $this->trimmed('fullname'); $homepage = $this->trimmed('homepage'); $bio = $this->trimmed('bio'); $location = $this->trimmed('location'); $autosubscribe = $this->boolean('autosubscribe'); $subscribe_policy = $this->trimmed('subscribe_policy'); $private_stream = $this->boolean('private_stream'); $language = $this->trimmed('language'); $timezone = $this->trimmed('timezone'); $tagstring = $this->trimmed('tags'); // Some validation if (!User::allowed_nickname($nickname)) { // TRANS: Validation error in form for profile settings. $this->showForm(_('Not a valid nickname.')); return; } else { if (!is_null($homepage) && strlen($homepage) > 0 && !Validate::uri($homepage, array('allowed_schemes' => array('http', 'https')))) { // TRANS: Validation error in form for profile settings. $this->showForm(_('Homepage is not a valid URL.')); return; } else { if (!is_null($fullname) && mb_strlen($fullname) > 255) { // TRANS: Validation error in form for profile settings. $this->showForm(_('Full name is too long (maximum 255 characters).')); return; } else { if (Profile::bioTooLong($bio)) { // TRANS: Validation error in form for profile settings. // TRANS: Plural form is used based on the maximum number of allowed // TRANS: characters for the biography (%d). $this->showForm(sprintf(_m('Bio is too long (maximum %d character).', 'Bio is too long (maximum %d characters).', Profile::maxBio()), Profile::maxBio())); return; } else { if (!is_null($location) && mb_strlen($location) > 255) { // TRANS: Validation error in form for profile settings. $this->showForm(_('Location is too long (maximum 255 characters).')); return; } else { if (is_null($timezone) || !in_array($timezone, DateTimeZone::listIdentifiers())) { // TRANS: Validation error in form for profile settings. $this->showForm(_('Timezone not selected.')); return; } else { if ($this->nicknameExists($nickname)) { // TRANS: Validation error in form for profile settings. $this->showForm(_('Nickname already in use. Try another one.')); return; } else { if (!is_null($language) && strlen($language) > 50) { // TRANS: Validation error in form for profile settings. $this->showForm(_('Language is too long (maximum 50 characters).')); return; } } } } } } } } $tags = array(); $tag_priv = array(); if (is_string($tagstring) && strlen($tagstring) > 0) { $tags = preg_split('/[\\s,]+/', $tagstring); foreach ($tags as &$tag) { $private = @$tag[0] === '.'; $tag = common_canonical_tag($tag); if (!common_valid_profile_tag($tag)) { // TRANS: Validation error in form for profile settings. // TRANS: %s is an invalid tag. $this->showForm(sprintf(_('Invalid tag: "%s".'), $tag)); return; } $tag_priv[$tag] = $private; } } $user = common_current_user(); $user->query('BEGIN'); if ($user->nickname != $nickname || $user->language != $language || $user->timezone != $timezone) { common_debug('Updating user nickname from ' . $user->nickname . ' to ' . $nickname, __FILE__); common_debug('Updating user language from ' . $user->language . ' to ' . $language, __FILE__); common_debug('Updating user timezone from ' . $user->timezone . ' to ' . $timezone, __FILE__); $original = clone $user; $user->nickname = $nickname; $user->language = $language; $user->timezone = $timezone; $result = $user->updateKeys($original); if ($result === false) { common_log_db_error($user, 'UPDATE', __FILE__); // TRANS: Server error thrown when user profile settings could not be updated. $this->serverError(_('Could not update user.')); return; } else { // Re-initialize language environment if it changed common_init_language(); // Clear the site owner, in case nickname changed if ($user->hasRole(Profile_role::OWNER)) { User::blow('user:site_owner'); } } } // XXX: XOR if ($user->autosubscribe ^ $autosubscribe || $user->private_stream ^ $private_stream || $user->subscribe_policy != $subscribe_policy) { $original = clone $user; $user->autosubscribe = $autosubscribe; $user->private_stream = $private_stream; $user->subscribe_policy = $subscribe_policy; $result = $user->update($original); if ($result === false) { common_log_db_error($user, 'UPDATE', __FILE__); // TRANS: Server error thrown when user profile settings could not be updated to // TRANS: automatically subscribe to any subscriber. $this->serverError(_('Could not update user for autosubscribe or subscribe_policy.')); return; } } $profile = $user->getProfile(); $orig_profile = clone $profile; $profile->nickname = $user->nickname; $profile->fullname = $fullname; $profile->homepage = $homepage; $profile->bio = $bio; $profile->location = $location; $loc = Location::fromName($location); if (empty($loc)) { $profile->lat = null; $profile->lon = null; $profile->location_id = null; $profile->location_ns = null; } else { $profile->lat = $loc->lat; $profile->lon = $loc->lon; $profile->location_id = $loc->location_id; $profile->location_ns = $loc->location_ns; } $profile->profileurl = common_profile_url($nickname); if (common_config('location', 'share') == 'user') { $exists = false; $prefs = User_location_prefs::staticGet('user_id', $user->id); if (empty($prefs)) { $prefs = new User_location_prefs(); $prefs->user_id = $user->id; $prefs->created = common_sql_now(); } else { $exists = true; $orig = clone $prefs; } $prefs->share_location = $this->boolean('sharelocation'); if ($exists) { $result = $prefs->update($orig); } else { $result = $prefs->insert(); } if ($result === false) { common_log_db_error($prefs, $exists ? 'UPDATE' : 'INSERT', __FILE__); // TRANS: Server error thrown when user profile location preference settings could not be updated. $this->serverError(_('Could not save location prefs.')); return; } } common_debug('Old profile: ' . common_log_objstring($orig_profile), __FILE__); common_debug('New profile: ' . common_log_objstring($profile), __FILE__); $result = $profile->update($orig_profile); if ($result === false) { common_log_db_error($profile, 'UPDATE', __FILE__); // TRANS: Server error thrown when user profile settings could not be saved. $this->serverError(_('Could not save profile.')); return; } // Set the user tags $result = $user->setSelfTags($tags, $tag_priv); if (!$result) { // TRANS: Server error thrown when user profile settings tags could not be saved. $this->serverError(_('Could not save tags.')); return; } $user->query('COMMIT'); Event::handle('EndProfileSaveForm', array($this)); common_broadcast_profile($profile); // TRANS: Confirmation shown when user profile settings are saved. $this->showForm(_('Settings saved.'), true); } }
/** * Handle a post * * Validate input and save changes. Reload the form with a success * or error message. * * @return void */ function handlePost() { // CSRF protection $token = $this->trimmed('token'); if (!$token || $token != common_session_token()) { $this->showForm(_('There was a problem with your session token. ' . 'Try again, please.')); return; } if (Event::handle('StartProfileSaveForm', array($this))) { $nickname = $this->trimmed('nickname'); $fullname = $this->trimmed('fullname'); $homepage = $this->trimmed('homepage'); $bio = $this->trimmed('bio'); $location = $this->trimmed('location'); $autosubscribe = $this->boolean('autosubscribe'); $language = $this->trimmed('language'); $timezone = $this->trimmed('timezone'); $tagstring = $this->trimmed('tags'); // Some validation if (!Validate::string($nickname, array('min_length' => 1, 'max_length' => 64, 'format' => NICKNAME_FMT))) { $this->showForm(_('Nickname must have only lowercase letters and numbers and no spaces.')); return; } else { if (!User::allowed_nickname($nickname)) { $this->showForm(_('Not a valid nickname.')); return; } else { if (!is_null($homepage) && strlen($homepage) > 0 && !Validate::uri($homepage, array('allowed_schemes' => array('http', 'https')))) { $this->showForm(_('Homepage is not a valid URL.')); return; } else { if (!is_null($fullname) && mb_strlen($fullname) > 255) { $this->showForm(_('Full name is too long (max 255 chars).')); return; } else { if (Profile::bioTooLong($bio)) { $this->showForm(sprintf(_('Bio is too long (max %d chars).'), Profile::maxBio())); return; } else { if (!is_null($location) && mb_strlen($location) > 255) { $this->showForm(_('Location is too long (max 255 chars).')); return; } else { if (is_null($timezone) || !in_array($timezone, DateTimeZone::listIdentifiers())) { $this->showForm(_('Timezone not selected.')); return; } else { if ($this->nicknameExists($nickname)) { $this->showForm(_('Nickname already in use. Try another one.')); return; } else { if (!is_null($language) && strlen($language) > 50) { $this->showForm(_('Language is too long (max 50 chars).')); return; } } } } } } } } } if ($tagstring) { $tags = array_map('common_canonical_tag', preg_split('/[\\s,]+/', $tagstring)); } else { $tags = array(); } foreach ($tags as $tag) { if (!common_valid_profile_tag($tag)) { $this->showForm(sprintf(_('Invalid tag: "%s"'), $tag)); return; } } $user = common_current_user(); $user->query('BEGIN'); if ($user->nickname != $nickname || $user->language != $language || $user->timezone != $timezone) { common_debug('Updating user nickname from ' . $user->nickname . ' to ' . $nickname, __FILE__); common_debug('Updating user language from ' . $user->language . ' to ' . $language, __FILE__); common_debug('Updating user timezone from ' . $user->timezone . ' to ' . $timezone, __FILE__); $original = clone $user; $user->nickname = $nickname; $user->language = $language; $user->timezone = $timezone; $result = $user->updateKeys($original); if ($result === false) { common_log_db_error($user, 'UPDATE', __FILE__); $this->serverError(_('Couldn\'t update user.')); return; } else { // Re-initialize language environment if it changed common_init_language(); // Clear the site owner, in case nickname changed if ($user->hasRole(Profile_role::OWNER)) { User::blow('user:site_owner'); } } } // XXX: XOR if ($user->autosubscribe ^ $autosubscribe) { $original = clone $user; $user->autosubscribe = $autosubscribe; $result = $user->update($original); if ($result === false) { common_log_db_error($user, 'UPDATE', __FILE__); $this->serverError(_('Couldn\'t update user for autosubscribe.')); return; } } $profile = $user->getProfile(); $orig_profile = clone $profile; $profile->nickname = $user->nickname; $profile->fullname = $fullname; $profile->homepage = $homepage; $profile->bio = $bio; $profile->location = $location; $loc = Location::fromName($location); if (empty($loc)) { $profile->lat = null; $profile->lon = null; $profile->location_id = null; $profile->location_ns = null; } else { $profile->lat = $loc->lat; $profile->lon = $loc->lon; $profile->location_id = $loc->location_id; $profile->location_ns = $loc->location_ns; } $profile->profileurl = common_profile_url($nickname); if (common_config('location', 'share') == 'user') { $exists = false; $prefs = User_location_prefs::staticGet('user_id', $user->id); if (empty($prefs)) { $prefs = new User_location_prefs(); $prefs->user_id = $user->id; $prefs->created = common_sql_now(); } else { $exists = true; $orig = clone $prefs; } $prefs->share_location = $this->boolean('sharelocation'); if ($exists) { $result = $prefs->update($orig); } else { $result = $prefs->insert(); } if ($result === false) { common_log_db_error($prefs, $exists ? 'UPDATE' : 'INSERT', __FILE__); $this->serverError(_('Couldn\'t save location prefs.')); return; } } common_debug('Old profile: ' . common_log_objstring($orig_profile), __FILE__); common_debug('New profile: ' . common_log_objstring($profile), __FILE__); $result = $profile->update($orig_profile); if ($result === false) { common_log_db_error($profile, 'UPDATE', __FILE__); $this->serverError(_('Couldn\'t save profile.')); return; } // Set the user tags $result = $user->setSelfTags($tags); if (!$result) { $this->serverError(_('Couldn\'t save tags.')); return; } $user->query('COMMIT'); Event::handle('EndProfileSaveForm', array($this)); common_broadcast_profile($profile); $this->showForm(_('Settings saved.'), true); } }
/** * Register a new user account and profile and set up default subscriptions. * If a new-user welcome message is configured, this will be sent. * * @param array $fields associative array of optional properties * string 'bio' * string 'email' * bool 'email_confirmed' pass true to mark email as pre-confirmed * string 'fullname' * string 'homepage' * string 'location' informal string description of geolocation * float 'lat' decimal latitude for geolocation * float 'lon' decimal longitude for geolocation * int 'location_id' geoname identifier * int 'location_ns' geoname namespace to interpret location_id * string 'nickname' REQUIRED * string 'password' (may be missing for eg OpenID registrations) * string 'code' invite code * ?string 'uri' permalink to notice; defaults to local notice URL * @return mixed User object or false on failure */ static function register($fields) { // MAGICALLY put fields into current scope extract($fields); $profile = new Profile(); if (!empty($email)) { $email = common_canonical_email($email); } $nickname = common_canonical_nickname($nickname); $profile->nickname = $nickname; if (!User::allowed_nickname($nickname)) { common_log(LOG_WARNING, sprintf("Attempted to register a nickname that is not allowed: %s", $profile->nickname), __FILE__); return false; } $profile->profileurl = common_profile_url($nickname); if (!empty($fullname)) { $profile->fullname = $fullname; } if (!empty($homepage)) { $profile->homepage = $homepage; } if (!empty($bio)) { $profile->bio = $bio; } if (!empty($location)) { $profile->location = $location; $loc = Location::fromName($location); if (!empty($loc)) { $profile->lat = $loc->lat; $profile->lon = $loc->lon; $profile->location_id = $loc->location_id; $profile->location_ns = $loc->location_ns; } } $profile->created = common_sql_now(); $user = new User(); $user->nickname = $nickname; // Users who respond to invite email have proven their ownership of that address if (!empty($code)) { $invite = Invitation::staticGet($code); if ($invite && $invite->address && $invite->address_type == 'email' && $invite->address == $email) { $user->email = $invite->address; } } if (isset($email_confirmed) && $email_confirmed) { $user->email = $email; } // This flag is ignored but still set to 1 $user->inboxed = 1; // Set default-on options here, otherwise they'll be disabled // initially for sites using caching, since the initial encache // doesn't know about the defaults in the database. $user->emailnotifysub = 1; $user->emailnotifyfav = 1; $user->emailnotifynudge = 1; $user->emailnotifymsg = 1; $user->emailnotifyattn = 1; $user->emailmicroid = 1; $user->emailpost = 1; $user->jabbermicroid = 1; $user->viewdesigns = 1; $user->created = common_sql_now(); if (Event::handle('StartUserRegister', array(&$user, &$profile))) { $profile->query('BEGIN'); $id = $profile->insert(); if (empty($id)) { common_log_db_error($profile, 'INSERT', __FILE__); return false; } $user->id = $id; if (!empty($uri)) { $user->uri = $uri; } else { $user->uri = common_user_uri($user); } if (!empty($password)) { // may not have a password for OpenID users $user->password = common_munge_password($password, $id); } $result = $user->insert(); if (!$result) { common_log_db_error($user, 'INSERT', __FILE__); return false; } // Everyone gets an inbox $inbox = new Inbox(); $inbox->user_id = $user->id; $inbox->notice_ids = ''; $result = $inbox->insert(); if (!$result) { common_log_db_error($inbox, 'INSERT', __FILE__); return false; } // Everyone is subscribed to themself $subscription = new Subscription(); $subscription->subscriber = $user->id; $subscription->subscribed = $user->id; $subscription->created = $user->created; $result = $subscription->insert(); if (!$result) { common_log_db_error($subscription, 'INSERT', __FILE__); return false; } if (!empty($email) && !$user->email) { $confirm = new Confirm_address(); $confirm->code = common_confirmation_code(128); $confirm->user_id = $user->id; $confirm->address = $email; $confirm->address_type = 'email'; $result = $confirm->insert(); if (!$result) { common_log_db_error($confirm, 'INSERT', __FILE__); return false; } } if (!empty($code) && $user->email) { $user->emailChanged(); } // Default system subscription $defnick = common_config('newuser', 'default'); if (!empty($defnick)) { $defuser = User::staticGet('nickname', $defnick); if (empty($defuser)) { common_log(LOG_WARNING, sprintf("Default user %s does not exist.", $defnick), __FILE__); } else { Subscription::start($user, $defuser); } } $profile->query('COMMIT'); if (!empty($email) && !$user->email) { mail_confirm_address($user, $confirm->code, $profile->nickname, $email); } // Welcome message $welcome = common_config('newuser', 'welcome'); if (!empty($welcome)) { $welcomeuser = User::staticGet('nickname', $welcome); if (empty($welcomeuser)) { common_log(LOG_WARNING, sprintf("Welcome user %s does not exist.", $defnick), __FILE__); } else { $notice = Notice::saveNew($welcomeuser->id, sprintf(_('Welcome to %1$s, @%2$s!'), common_config('site', 'name'), $user->nickname), 'system'); } } Event::handle('EndUserRegister', array(&$profile, &$user)); } return $user; }
function validateOmb() { $listener = $_GET['omb_listener']; $listenee = $_GET['omb_listenee']; $nickname = $_GET['omb_listenee_nickname']; $profile = $_GET['omb_listenee_profile']; $user = User::staticGet('uri', $listener); if (!$user) { // TRANS: Exception thrown when no valid user is found for an authorisation request. // TRANS: %s is a listener URI. throw new Exception(sprintf(_('Listener URI "%s" not found here.'), $listener)); } if (strlen($listenee) > 255) { // TRANS: Exception thrown when listenee URI is too long for an authorisation request. // TRANS: %s is a listenee URI. throw new Exception(sprintf(_('Listenee URI "%s" is too long.'), $listenee)); } $other = User::staticGet('uri', $listenee); if ($other) { // TRANS: Exception thrown when listenee URI is a local user for an authorisation request. // TRANS: %s is a listenee URI. throw new Exception(sprintf(_('Listenee URI "%s" is a local user.'), $listenee)); } $remote = Remote_profile::staticGet('uri', $listenee); if ($remote) { $sub = new Subscription(); $sub->subscriber = $user->id; $sub->subscribed = $remote->id; if ($sub->find(true)) { // TRANS: Exception thrown when already subscribed. throw new Exception('You are already subscribed to this user.'); } } if ($profile == common_profile_url($nickname)) { // TRANS: Exception thrown when profile URL is a local user for an authorisation request. // TRANS: %s is a profile URL. throw new Exception(sprintf(_('Profile URL "%s" is for a local user.'), $profile)); } $license = $_GET['omb_listenee_license']; $site_license = common_config('license', 'url'); if (!common_compatible_license($license, $site_license)) { // TRANS: Exception thrown when licenses are not compatible for an authorisation request. // TRANS: %1$s is the license for the listenee, %2$s is the license for "this" StatusNet site. throw new Exception(sprintf(_('Listenee stream license "%1$s" is not ' . 'compatible with site license "%2$s".'), $license, $site_license)); } $avatar = $_GET['omb_listenee_avatar']; if ($avatar) { if (!common_valid_http_url($avatar) || strlen($avatar) > 255) { // TRANS: Exception thrown when avatar URL is invalid for an authorisation request. // TRANS: %s is an avatar URL. throw new Exception(sprintf(_('Avatar URL "%s" is not valid.'), $avatar)); } $size = @getimagesize($avatar); if (!$size) { // TRANS: Exception thrown when avatar URL could not be read for an authorisation request. // TRANS: %s is an avatar URL. throw new Exception(sprintf(_('Cannot read avatar URL "%s".'), $avatar)); } if (!in_array($size[2], array(IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG))) { // TRANS: Exception thrown when avatar URL return an invalid image type for an authorisation request. // TRANS: %s is an avatar URL. throw new Exception(sprintf(_('Wrong image type for avatar URL ' . '"%s".'), $avatar)); } } }
function validateOmb() { $listener = $_GET['omb_listener']; $listenee = $_GET['omb_listenee']; $nickname = $_GET['omb_listenee_nickname']; $profile = $_GET['omb_listenee_profile']; $user = User::staticGet('uri', $listener); if (!$user) { throw new Exception(sprintf(_('Listener URI ‘%s’ not found here.'), $listener)); } if (strlen($listenee) > 255) { throw new Exception(sprintf(_('Listenee URI ‘%s’ is too long.'), $listenee)); } $other = User::staticGet('uri', $listenee); if ($other) { throw new Exception(sprintf(_('Listenee URI ‘%s’ is a local user.'), $listenee)); } $remote = Remote_profile::staticGet('uri', $listenee); if ($remote) { $sub = new Subscription(); $sub->subscriber = $user->id; $sub->subscribed = $remote->id; if ($sub->find(true)) { throw new Exception('You are already subscribed to this user.'); } } if ($profile == common_profile_url($nickname)) { throw new Exception(sprintf(_('Profile URL ‘%s’ is for a local user.'), $profile)); } $license = $_GET['omb_listenee_license']; $site_license = common_config('license', 'url'); if (!common_compatible_license($license, $site_license)) { throw new Exception(sprintf(_('Listenee stream license ‘%1$s’ is not ' . 'compatible with site license ‘%2$s’.'), $license, $site_license)); } $avatar = $_GET['omb_listenee_avatar']; if ($avatar) { if (!common_valid_http_url($avatar) || strlen($avatar) > 255) { throw new Exception(sprintf(_('Avatar URL ‘%s’ is not valid.'), $avatar)); } $size = @getimagesize($avatar); if (!$size) { throw new Exception(sprintf(_('Can’t read avatar URL ‘%s’.'), $avatar)); } if (!in_array($size[2], array(IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG))) { throw new Exception(sprintf(_('Wrong image type for avatar URL ' . '‘%s’.'), $avatar)); } } }
function generateAllowResponse($request, $user) { $response = $request->answer(true, null, common_profile_url($user->nickname)); $profile = $user->getProfile(); $sreg_data = array('fullname' => $profile->fullname, 'nickname' => $user->nickname, 'email' => $user->email, 'language' => $user->language, 'timezone' => $user->timezone); $sreg_request = Auth_OpenID_SRegRequest::fromOpenIDRequest($request); $sreg_response = Auth_OpenID_SRegResponse::extractResponse($sreg_request, $sreg_data); $sreg_response->toMessage($response->fields); return $response; }
/** * Handle a post * * Validate input and save changes. Reload the form with a success * or error message. * * @return void */ protected function doPost() { if (Event::handle('StartProfileSaveForm', array($this))) { // $nickname will only be set if this changenick value is true. if (common_config('profile', 'changenick') == true) { try { $nickname = Nickname::normalize($this->trimmed('nickname'), true); } catch (NicknameTakenException $e) { // Abort only if the nickname is occupied by _another_ local user profile if (!$this->scoped->sameAs($e->profile)) { throw $e; } // Since the variable wasn't set before the exception was thrown, let's run // the normalize sequence again, but without in-use check this time. $nickname = Nickname::normalize($this->trimmed('nickname')); } } $fullname = $this->trimmed('fullname'); $homepage = $this->trimmed('homepage'); $bio = $this->trimmed('bio'); $location = $this->trimmed('location'); $autosubscribe = $this->booleanintstring('autosubscribe'); $subscribe_policy = $this->trimmed('subscribe_policy'); $private_stream = $this->booleanintstring('private_stream'); $language = $this->trimmed('language'); $timezone = $this->trimmed('timezone'); $tagstring = $this->trimmed('tags'); // Some validation if (!is_null($homepage) && strlen($homepage) > 0 && !common_valid_http_url($homepage)) { // TRANS: Validation error in form for profile settings. throw new ClientException(_('Homepage is not a valid URL.')); } else { if (!is_null($fullname) && mb_strlen($fullname) > 191) { // TRANS: Validation error in form for profile settings. throw new ClientException(_('Full name is too long (maximum 191 characters).')); } else { if (Profile::bioTooLong($bio)) { // TRANS: Validation error in form for profile settings. // TRANS: Plural form is used based on the maximum number of allowed // TRANS: characters for the biography (%d). throw new ClientException(sprintf(_m('Bio is too long (maximum %d character).', 'Bio is too long (maximum %d characters).', Profile::maxBio()), Profile::maxBio())); } else { if (!is_null($location) && mb_strlen($location) > 191) { // TRANS: Validation error in form for profile settings. throw new ClientException(_('Location is too long (maximum 191 characters).')); } else { if (is_null($timezone) || !in_array($timezone, DateTimeZone::listIdentifiers())) { // TRANS: Validation error in form for profile settings. throw new ClientException(_('Timezone not selected.')); } else { if (!is_null($language) && strlen($language) > 50) { // TRANS: Validation error in form for profile settings. throw new ClientException(_('Language is too long (maximum 50 characters).')); } } } } } } $tags = array(); $tag_priv = array(); if (is_string($tagstring) && strlen($tagstring) > 0) { $tags = preg_split('/[\\s,]+/', $tagstring); foreach ($tags as &$tag) { $private = @$tag[0] === '.'; $tag = common_canonical_tag($tag); if (!common_valid_profile_tag($tag)) { // TRANS: Validation error in form for profile settings. // TRANS: %s is an invalid tag. throw new ClientException(sprintf(_('Invalid tag: "%s".'), $tag)); } $tag_priv[$tag] = $private; } } $user = $this->scoped->getUser(); $user->query('BEGIN'); // $user->nickname is updated through Profile->update(); // XXX: XOR if ($user->autosubscribe ^ $autosubscribe || $user->private_stream ^ $private_stream || $user->timezone != $timezone || $user->language != $language || $user->subscribe_policy != $subscribe_policy) { $original = clone $user; $user->autosubscribe = $autosubscribe; $user->language = $language; $user->private_stream = $private_stream; $user->subscribe_policy = $subscribe_policy; $user->timezone = $timezone; $result = $user->update($original); if ($result === false) { common_log_db_error($user, 'UPDATE', __FILE__); $user->query('ROLLBACK'); // TRANS: Server error thrown when user profile settings could not be updated to // TRANS: automatically subscribe to any subscriber. throw new ServerException(_('Could not update user for autosubscribe or subscribe_policy.')); } // Re-initialize language environment if it changed common_init_language(); } $original = clone $this->scoped; if (common_config('profile', 'changenick') == true && $this->scoped->getNickname() !== $nickname) { assert(Nickname::normalize($nickname) === $nickname); common_debug("Changing user nickname from '{$this->scoped->getNickname()}' to '{$nickname}'."); $this->scoped->nickname = $nickname; $this->scoped->profileurl = common_profile_url($this->scoped->getNickname()); } $this->scoped->fullname = $fullname; $this->scoped->homepage = $homepage; $this->scoped->bio = $bio; $this->scoped->location = $location; $loc = Location::fromName($location); if (empty($loc)) { $this->scoped->lat = null; $this->scoped->lon = null; $this->scoped->location_id = null; $this->scoped->location_ns = null; } else { $this->scoped->lat = $loc->lat; $this->scoped->lon = $loc->lon; $this->scoped->location_id = $loc->location_id; $this->scoped->location_ns = $loc->location_ns; } if (common_config('location', 'share') == 'user') { $exists = false; $prefs = User_location_prefs::getKV('user_id', $this->scoped->getID()); if (empty($prefs)) { $prefs = new User_location_prefs(); $prefs->user_id = $this->scoped->getID(); $prefs->created = common_sql_now(); } else { $exists = true; $orig = clone $prefs; } $prefs->share_location = $this->booleanintstring('sharelocation'); if ($exists) { $result = $prefs->update($orig); } else { $result = $prefs->insert(); } if ($result === false) { common_log_db_error($prefs, $exists ? 'UPDATE' : 'INSERT', __FILE__); $user->query('ROLLBACK'); // TRANS: Server error thrown when user profile location preference settings could not be updated. throw new ServerException(_('Could not save location prefs.')); } } common_debug('Old profile: ' . common_log_objstring($original), __FILE__); common_debug('New profile: ' . common_log_objstring($this->scoped), __FILE__); $result = $this->scoped->update($original); if ($result === false) { common_log_db_error($this->scoped, 'UPDATE', __FILE__); $user->query('ROLLBACK'); // TRANS: Server error thrown when user profile settings could not be saved. throw new ServerException(_('Could not save profile.')); } // Set the user tags $result = Profile_tag::setSelfTags($this->scoped, $tags, $tag_priv); $user->query('COMMIT'); Event::handle('EndProfileSaveForm', array($this)); // TRANS: Confirmation shown when user profile settings are saved. return _('Settings saved.'); } }
/** * Register a new user account and profile and set up default subscriptions. * If a new-user welcome message is configured, this will be sent. * * @param array $fields associative array of optional properties * string 'bio' * string 'email' * bool 'email_confirmed' pass true to mark email as pre-confirmed * string 'fullname' * string 'homepage' * string 'location' informal string description of geolocation * float 'lat' decimal latitude for geolocation * float 'lon' decimal longitude for geolocation * int 'location_id' geoname identifier * int 'location_ns' geoname namespace to interpret location_id * string 'nickname' REQUIRED * string 'password' (may be missing for eg OpenID registrations) * string 'code' invite code * ?string 'uri' permalink to notice; defaults to local notice URL * @return User object * @throws Exception on failure */ static function register(array $fields) { // MAGICALLY put fields into current scope extract($fields); $profile = new Profile(); if (!empty($email)) { $email = common_canonical_email($email); } // Normalize _and_ check whether it is in use. Throw NicknameException on failure. $profile->nickname = Nickname::normalize($nickname, true); $profile->profileurl = common_profile_url($profile->nickname); if (!empty($fullname)) { $profile->fullname = $fullname; } if (!empty($homepage)) { $profile->homepage = $homepage; } if (!empty($bio)) { $profile->bio = $bio; } if (!empty($location)) { $profile->location = $location; $loc = Location::fromName($location); if (!empty($loc)) { $profile->lat = $loc->lat; $profile->lon = $loc->lon; $profile->location_id = $loc->location_id; $profile->location_ns = $loc->location_ns; } } $profile->created = common_sql_now(); $user = new User(); $user->nickname = $profile->nickname; $invite = null; // Users who respond to invite email have proven their ownership of that address if (!empty($code)) { $invite = Invitation::getKV($code); if ($invite instanceof Invitation && $invite->address && $invite->address_type == 'email' && $invite->address == $email) { $user->email = $invite->address; } } if (isset($email_confirmed) && $email_confirmed) { $user->email = $email; } // Set default-on options here, otherwise they'll be disabled // initially for sites using caching, since the initial encache // doesn't know about the defaults in the database. $user->emailnotifysub = 1; $user->emailnotifynudge = 1; $user->emailnotifymsg = 1; $user->emailnotifyattn = 1; $user->emailmicroid = 1; $user->emailpost = 1; $user->jabbermicroid = 1; $user->created = common_sql_now(); if (Event::handle('StartUserRegister', array($profile))) { $profile->query('BEGIN'); $id = $profile->insert(); if ($id === false) { common_log_db_error($profile, 'INSERT', __FILE__); $profile->query('ROLLBACK'); // TRANS: Profile data could not be inserted for some reason. throw new ServerException(_m('Could not insert profile data for new user.')); } $user->id = $id; if (!empty($uri)) { $user->uri = $uri; } else { $user->uri = common_user_uri($user); } if (!empty($password)) { // may not have a password for OpenID users $user->password = common_munge_password($password, $id); } $result = $user->insert(); if ($result === false) { common_log_db_error($user, 'INSERT', __FILE__); $profile->query('ROLLBACK'); // TRANS: User data could not be inserted for some reason. throw new ServerException(_m('Could not insert user data for new user.')); } // Everyone is subscribed to themself $subscription = new Subscription(); $subscription->subscriber = $user->id; $subscription->subscribed = $user->id; $subscription->created = $user->created; $result = $subscription->insert(); if (!$result) { common_log_db_error($subscription, 'INSERT', __FILE__); $profile->query('ROLLBACK'); // TRANS: Subscription data could not be inserted for some reason. throw new ServerException(_m('Could not insert subscription data for new user.')); } // Mark that this invite was converted if (!empty($invite)) { $invite->convert($user); } if (!empty($email) && !$user->email) { $confirm = new Confirm_address(); $confirm->code = common_confirmation_code(128); $confirm->user_id = $user->id; $confirm->address = $email; $confirm->address_type = 'email'; $result = $confirm->insert(); if (!$result) { common_log_db_error($confirm, 'INSERT', __FILE__); $profile->query('ROLLBACK'); // TRANS: Email confirmation data could not be inserted for some reason. throw new ServerException(_m('Could not insert email confirmation data for new user.')); } } if (!empty($code) && $user->email) { $user->emailChanged(); } // Default system subscription $defnick = common_config('newuser', 'default'); if (!empty($defnick)) { $defuser = User::getKV('nickname', $defnick); if (empty($defuser)) { common_log(LOG_WARNING, sprintf("Default user %s does not exist.", $defnick), __FILE__); } else { Subscription::ensureStart($profile, $defuser->getProfile()); } } $profile->query('COMMIT'); if (!empty($email) && !$user->email) { mail_confirm_address($user, $confirm->code, $profile->nickname, $email); } // Welcome message $welcome = common_config('newuser', 'welcome'); if (!empty($welcome)) { $welcomeuser = User::getKV('nickname', $welcome); if (empty($welcomeuser)) { common_log(LOG_WARNING, sprintf("Welcome user %s does not exist.", $defnick), __FILE__); } else { $notice = Notice::saveNew($welcomeuser->id, sprintf(_('Welcome to %1$s, @%2$s!'), common_config('site', 'name'), $user->nickname), 'system'); } } Event::handle('EndUserRegister', array($profile)); } if (!$user instanceof User) { throw new ServerException('User could not be registered. Probably an event hook that failed.'); } return $user; }
function omb_update_profile($profile, $remote_profile, $subscription) { $user = User::staticGet($profile->id); $con = omb_oauth_consumer(); $token = new OAuthToken($subscription->token, $subscription->secret); $url = $remote_profile->updateprofileurl; $parsed = parse_url($url); $params = array(); parse_str($parsed['query'], $params); $req = OAuthRequest::from_consumer_and_token($con, $token, "POST", $url, $params); $req->set_parameter('omb_version', OMB_VERSION_01); $req->set_parameter('omb_listenee', $user->uri); $req->set_parameter('omb_listenee_profile', common_profile_url($profile->nickname)); $req->set_parameter('omb_listenee_nickname', $profile->nickname); # We use blanks to force emptying any existing values in these optional fields $req->set_parameter('omb_listenee_fullname', $profile->fullname ? $profile->fullname : ''); $req->set_parameter('omb_listenee_homepage', $profile->homepage ? $profile->homepage : ''); $req->set_parameter('omb_listenee_bio', $profile->bio ? $profile->bio : ''); $req->set_parameter('omb_listenee_location', $profile->location ? $profile->location : ''); $avatar = $profile->getAvatar(AVATAR_PROFILE_SIZE); $req->set_parameter('omb_listenee_avatar', $avatar ? $avatar->url : ''); $req->sign_request(omb_hmac_sha1(), $con, $token); # We re-use this tool's fetcher, since it's pretty good $fetcher = Auth_Yadis_Yadis::getHTTPFetcher(); common_debug('request URL = ' . $req->get_normalized_http_url(), __FILE__); common_debug('postdata = ' . $req->to_postdata(), __FILE__); $result = $fetcher->post($req->get_normalized_http_url(), $req->to_postdata(), array('User-Agent: Laconica/' . LACONICA_VERSION)); common_debug('Got HTTP result "' . print_r($result, true) . '"', __FILE__); if (empty($result) || !$result) { common_debug("Unable to contact " . $req->get_normalized_http_url()); } else { if ($result->status == 403) { # not authorized, don't send again common_debug('403 result, deleting subscription', __FILE__); $subscription->delete(); return false; } else { if ($result->status != 200) { common_debug('Error status ' . $result->status, __FILE__); return false; } else { # success! parse_str($result->body, $return); if (isset($return['omb_version']) && $return['omb_version'] === OMB_VERSION_01) { return true; } else { return false; } } } } }
/** * Handle a post * * Validate input and save changes. Reload the form with a success * or error message. * * @return void */ function handlePost() { # CSRF protection $token = $this->trimmed('token'); if (!$token || $token != common_session_token()) { $this->showForm(_('There was a problem with your session token. ' . 'Try again, please.')); return; } $nickname = $this->trimmed('nickname'); $fullname = $this->trimmed('fullname'); $homepage = $this->trimmed('homepage'); $bio = $this->trimmed('bio'); $location = $this->trimmed('location'); $autosubscribe = $this->boolean('autosubscribe'); $language = $this->trimmed('language'); $timezone = $this->trimmed('timezone'); $tagstring = $this->trimmed('tags'); # Some validation if (!Validate::string($nickname, array('min_length' => 1, 'max_length' => 64, 'format' => VALIDATE_NUM . VALIDATE_ALPHA_LOWER))) { $this->showForm(_('Nickname must have only lowercase letters and numbers and no spaces.')); return; } else { if (!User::allowed_nickname($nickname)) { $this->showForm(_('Not a valid nickname.')); return; } else { if (!is_null($homepage) && strlen($homepage) > 0 && !Validate::uri($homepage, array('allowed_schemes' => array('http', 'https')))) { $this->showForm(_('Homepage is not a valid URL.')); return; } else { if (!is_null($fullname) && mb_strlen($fullname) > 255) { $this->showForm(_('Full name is too long (max 255 chars).')); return; } else { if (!is_null($bio) && mb_strlen($bio) > 140) { $this->showForm(_('Bio is too long (max 140 chars).')); return; } else { if (!is_null($location) && mb_strlen($location) > 255) { $this->showForm(_('Location is too long (max 255 chars).')); return; } else { if (is_null($timezone) || !in_array($timezone, DateTimeZone::listIdentifiers())) { $this->showForm(_('Timezone not selected.')); return; } else { if ($this->nicknameExists($nickname)) { $this->showForm(_('Nickname already in use. Try another one.')); return; } else { if (!is_null($language) && strlen($language) > 50) { $this->showForm(_('Language is too long (max 50 chars).')); return; } } } } } } } } } if ($tagstring) { $tags = array_map('common_canonical_tag', preg_split('/[\\s,]+/', $tagstring)); } else { $tags = array(); } foreach ($tags as $tag) { if (!common_valid_profile_tag($tag)) { $this->showForm(sprintf(_('Invalid tag: "%s"'), $tag)); return; } } $user = common_current_user(); $user->query('BEGIN'); if ($user->nickname != $nickname || $user->language != $language || $user->timezone != $timezone) { common_debug('Updating user nickname from ' . $user->nickname . ' to ' . $nickname, __FILE__); common_debug('Updating user language from ' . $user->language . ' to ' . $language, __FILE__); common_debug('Updating user timezone from ' . $user->timezone . ' to ' . $timezone, __FILE__); $original = clone $user; $user->nickname = $nickname; $user->language = $language; $user->timezone = $timezone; $result = $user->updateKeys($original); if ($result === false) { common_log_db_error($user, 'UPDATE', __FILE__); $this->serverError(_('Couldn\'t update user.')); return; } else { # Re-initialize language environment if it changed common_init_language(); } } # XXX: XOR if ($user->autosubscribe ^ $autosubscribe) { $original = clone $user; $user->autosubscribe = $autosubscribe; $result = $user->update($original); if ($result === false) { common_log_db_error($user, 'UPDATE', __FILE__); $this->serverError(_('Couldn\'t update user for autosubscribe.')); return; } } $profile = $user->getProfile(); $orig_profile = clone $profile; $profile->nickname = $user->nickname; $profile->fullname = $fullname; $profile->homepage = $homepage; $profile->bio = $bio; $profile->location = $location; $profile->profileurl = common_profile_url($nickname); common_debug('Old profile: ' . common_log_objstring($orig_profile), __FILE__); common_debug('New profile: ' . common_log_objstring($profile), __FILE__); $result = $profile->update($orig_profile); if (!$result) { common_log_db_error($profile, 'UPDATE', __FILE__); $this->serverError(_('Couldn\'t save profile.')); return; } # Set the user tags $result = $user->setSelfTags($tags); if (!$result) { $this->serverError(_('Couldn\'t save tags.')); return; } $user->query('COMMIT'); common_broadcast_profile($profile); $this->showForm(_('Settings saved.'), true); }
function updateProfileUrl($profile) { $orig = clone $profile; $profile->profileurl = common_profile_url($profile->nickname); $profile->update($orig); }
function requestAuthorization($user, $omb, $token, $secret) { $con = omb_oauth_consumer(); $tok = new OAuthToken($token, $secret); $url = omb_service_uri($omb[OAUTH_ENDPOINT_AUTHORIZE]); # XXX: Is this the right thing to do? Strip off GET params and make them # POST params? Seems wrong to me. $parsed = parse_url($url); $params = array(); parse_str($parsed['query'], $params); $req = OAuthRequest::from_consumer_and_token($con, $tok, 'GET', $url, $params); # We send over a ton of information. This lets the other # server store info about our user, and it lets the current # user decide if they really want to authorize the subscription. $req->set_parameter('omb_version', OMB_VERSION_01); $req->set_parameter('omb_listener', omb_local_id($omb[OAUTH_ENDPOINT_REQUEST])); $req->set_parameter('omb_listenee', $user->uri); $req->set_parameter('omb_listenee_profile', common_profile_url($user->nickname)); $req->set_parameter('omb_listenee_nickname', $user->nickname); $req->set_parameter('omb_listenee_license', common_config('license', 'url')); $profile = $user->getProfile(); if (!$profile) { common_log_db_error($user, 'SELECT', __FILE__); $this->serverError(_('User without matching profile')); return; } if (!is_null($profile->fullname)) { $req->set_parameter('omb_listenee_fullname', $profile->fullname); } if (!is_null($profile->homepage)) { $req->set_parameter('omb_listenee_homepage', $profile->homepage); } if (!is_null($profile->bio)) { $req->set_parameter('omb_listenee_bio', $profile->bio); } if (!is_null($profile->location)) { $req->set_parameter('omb_listenee_location', $profile->location); } $avatar = $profile->getAvatar(AVATAR_PROFILE_SIZE); if ($avatar) { $req->set_parameter('omb_listenee_avatar', $avatar->url); } # XXX: add a nonce to prevent replay attacks $req->set_parameter('oauth_callback', common_local_url('finishremotesubscribe')); # XXX: test to see if endpoint accepts this signature method $req->sign_request(omb_hmac_sha1(), $con, $tok); # store all our info here $omb['listenee'] = $user->nickname; $omb['listener'] = omb_local_id($omb[OAUTH_ENDPOINT_REQUEST]); $omb['token'] = $token; $omb['secret'] = $secret; # call doesn't work after bounce back so we cache; maybe serialization issue...? $omb['access_token_url'] = omb_service_uri($omb[OAUTH_ENDPOINT_ACCESS]); $omb['post_notice_url'] = omb_service_uri($omb[OMB_ENDPOINT_POSTNOTICE]); $omb['update_profile_url'] = omb_service_uri($omb[OMB_ENDPOINT_UPDATEPROFILE]); common_ensure_session(); $_SESSION['oauth_authorization_request'] = $omb; # Redirect to authorization service common_redirect($req->to_url()); return; }
/** * User XRDS output hook * * Puts the bits of code needed to discover OpenID endpoints. * * @param Action $action Action being executed * @param XMLOutputter &$xrdsOutputter Output channel * * @return boolean hook return */ function onEndUserXRDS($action, &$xrdsOutputter) { $xrdsOutputter->elementStart('XRD', array('xmlns' => 'xri://$xrd*($v*2.0)', 'xml:id' => 'openid', 'xmlns:simple' => 'http://xrds-simple.net/core/1.0', 'version' => '2.0')); $xrdsOutputter->element('Type', null, 'xri://$xrds*simple'); //consumer $xrdsOutputter->showXrdsService('http://specs.openid.net/auth/2.0/return_to', common_local_url('finishopenidlogin')); //provider $xrdsOutputter->showXrdsService('http://specs.openid.net/auth/2.0/signon', common_local_url('openidserver'), null, null, common_profile_url($action->user->nickname)); $xrdsOutputter->elementEnd('XRD'); }
/** * Save fields that should be stored in the main profile object * * XXX: There's a lot of dupe code here from ProfileSettingsAction. * Do not want. * * @param User $user the current user */ function saveStandardProfileDetails($user) { $fullname = $this->trimmed('extprofile-fullname'); $location = $this->trimmed('extprofile-location'); $tagstring = $this->trimmed('extprofile-tags'); $bio = $this->trimmed('extprofile-bio'); if ($tagstring) { $tags = array_map('common_canonical_tag', preg_split('/[\\s,]+/', $tagstring)); } else { $tags = array(); } foreach ($tags as $tag) { if (!common_valid_profile_tag($tag)) { // TRANS: Validation error in form for profile settings. // TRANS: %s is an invalid tag. throw new Exception(sprintf(_m('Invalid tag: "%s".'), $tag)); } } $profile = $user->getProfile(); $oldTags = $user->getSelfTags(); $newTags = array_diff($tags, $oldTags); if ($fullname != $profile->fullname || $location != $profile->location || !empty($newTags) || $bio != $profile->bio) { $orig = clone $profile; $profile->nickname = $user->nickname; $profile->fullname = $fullname; $profile->bio = $bio; $profile->location = $location; $loc = Location::fromName($location); if (empty($loc)) { $profile->lat = null; $profile->lon = null; $profile->location_id = null; $profile->location_ns = null; } else { $profile->lat = $loc->lat; $profile->lon = $loc->lon; $profile->location_id = $loc->location_id; $profile->location_ns = $loc->location_ns; } $profile->profileurl = common_profile_url($user->nickname); $result = $profile->update($orig); if ($result === false) { common_log_db_error($profile, 'UPDATE', __FILE__); // TRANS: Server error thrown when user profile settings could not be saved. $this->serverError(_m('Could not save profile.')); } // Set the user tags $result = $user->setSelfTags($tags); if (!$result) { // TRANS: Server error thrown when user profile settings tags could not be saved. $this->serverError(_m('Could not save tags.')); } Event::handle('EndProfileSaveForm', array($this)); } }
/** * Save passed profile * * Stores the OMB profile $profile. Overwrites an existing entry. * Throws exceptions in case of error. * * @param OMB_Profile $profile The OMB profile which should be saved * * @access public **/ public function saveProfile($omb_profile) { if (common_profile_url($omb_profile->getNickname()) == $omb_profile->getProfileURL()) { throw new Exception('Not implemented'); } else { $remote = Remote_profile::staticGet('uri', $omb_profile->getIdentifierURI()); if ($remote) { $exists = true; $profile = Profile::staticGet($remote->id); $orig_remote = clone $remote; $orig_profile = clone $profile; // XXX: compare current postNotice and updateProfile URLs to the ones // stored in the DB to avoid (possibly...) above attack } else { $exists = false; $remote = new Remote_profile(); $remote->uri = $omb_profile->getIdentifierURI(); $profile = new Profile(); } $profile->nickname = $omb_profile->getNickname(); $profile->profileurl = $omb_profile->getProfileURL(); $fullname = $omb_profile->getFullname(); $profile->fullname = is_null($fullname) ? '' : $fullname; $homepage = $omb_profile->getHomepage(); $profile->homepage = is_null($homepage) ? '' : $homepage; $bio = $omb_profile->getBio(); $profile->bio = is_null($bio) ? '' : $bio; $location = $omb_profile->getLocation(); $profile->location = is_null($location) ? '' : $location; if ($exists) { $profile->update($orig_profile); } else { $profile->created = DB_DataObject_Cast::dateTime(); # current time $id = $profile->insert(); if (!$id) { // TRANS: Exception thrown when creating a new profile fails in OAuth store. throw new Exception(_('Error inserting new profile.')); } $remote->id = $id; } $avatar_url = $omb_profile->getAvatarURL(); if ($avatar_url) { if (!$this->add_avatar($profile, $avatar_url)) { // TRANS: Exception thrown when creating a new avatar fails in OAuth store. throw new Exception(_('Error inserting avatar.')); } } else { $avatar = $profile->getOriginalAvatar(); if ($avatar) { $avatar->delete(); } $avatar = $profile->getAvatar(AVATAR_PROFILE_SIZE); if ($avatar) { $avatar->delete(); } $avatar = $profile->getAvatar(AVATAR_STREAM_SIZE); if ($avatar) { $avatar->delete(); } $avatar = $profile->getAvatar(AVATAR_MINI_SIZE); if ($avatar) { $avatar->delete(); } } if ($exists) { if (!$remote->update($orig_remote)) { // TRANS: Exception thrown when updating a remote profile fails in OAuth store. throw new Exception(_('Error updating remote profile.')); } } else { $remote->created = DB_DataObject_Cast::dateTime(); # current time if (!$remote->insert()) { // TRANS: Exception thrown when creating a remote profile fails in OAuth store. throw new Exception(_('Error inserting remote profile.')); } } } }
static function register($fields) { # MAGICALLY put fields into current scope extract($fields); $profile = new Profile(); $profile->query('BEGIN'); $profile->nickname = $nickname; $profile->profileurl = common_profile_url($nickname); if (!empty($fullname)) { $profile->fullname = $fullname; } if (!empty($homepage)) { $profile->homepage = $homepage; } if (!empty($bio)) { $profile->bio = $bio; } if (!empty($location)) { $profile->location = $location; } $profile->created = common_sql_now(); $id = $profile->insert(); if (empty($id)) { common_log_db_error($profile, 'INSERT', __FILE__); return false; } $user = new User(); $user->id = $id; $user->nickname = $nickname; if (!empty($password)) { # may not have a password for OpenID users $user->password = common_munge_password($password, $id); } # Users who respond to invite email have proven their ownership of that address if (!empty($code)) { $invite = Invitation::staticGet($code); if ($invite && $invite->address && $invite->address_type == 'email' && $invite->address == $email) { $user->email = $invite->address; } } $inboxes = common_config('inboxes', 'enabled'); if ($inboxes === true || $inboxes == 'transitional') { $user->inboxed = 1; } $user->created = common_sql_now(); $user->uri = common_user_uri($user); $result = $user->insert(); if (!$result) { common_log_db_error($user, 'INSERT', __FILE__); return false; } # Everyone is subscribed to themself $subscription = new Subscription(); $subscription->subscriber = $user->id; $subscription->subscribed = $user->id; $subscription->created = $user->created; $result = $subscription->insert(); if (!$result) { common_log_db_error($subscription, 'INSERT', __FILE__); return false; } if (!empty($email) && !$user->email) { $confirm = new Confirm_address(); $confirm->code = common_confirmation_code(128); $confirm->user_id = $user->id; $confirm->address = $email; $confirm->address_type = 'email'; $result = $confirm->insert(); if (!$result) { common_log_db_error($confirm, 'INSERT', __FILE__); return false; } } if (!empty($code) && $user->email) { $user->emailChanged(); } $profile->query('COMMIT'); if ($email && !$user->email) { mail_confirm_address($user, $confirm->code, $profile->nickname, $email); } return $user; }