SL-9699 Login selection

master
andreykproductengine 2019-08-09 21:34:12 +03:00
parent db6275b9f7
commit 99a4bd23da
20 changed files with 1054 additions and 161 deletions

View File

@ -246,6 +246,7 @@ set(viewer_SOURCE_FILES
llfloaterexperiences.cpp
llfloaterflickr.cpp
llfloaterfonttest.cpp
llfloaterforgetuser.cpp
llfloatergesture.cpp
llfloatergodtools.cpp
llfloatergotoline.cpp
@ -871,6 +872,7 @@ set(viewer_HEADER_FILES
llfloaterexperiences.h
llfloaterflickr.h
llfloaterfonttest.h
llfloaterforgetuser.h
llfloatergesture.h
llfloatergodtools.h
llfloatergotoline.h

View File

@ -8434,6 +8434,17 @@
<key>Value</key>
<integer>1</integer>
</map>
<key>RememberUser</key>
<map>
<key>Comment</key>
<string>Keep user name for next login</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>RememberPassword</key>
<map>
<key>Comment</key>

View File

@ -1493,18 +1493,24 @@ void LLFavoritesOrderStorage::getSLURL(const LLUUID& asset_id)
}
// static
std::string LLFavoritesOrderStorage::getStoredFavoritesFilename()
std::string LLFavoritesOrderStorage::getStoredFavoritesFilename(const std::string &grid)
{
std::string user_dir = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "");
std::string user_dir = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "");
return (user_dir.empty() ? ""
: gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,
"stored_favorites_"
+ LLGridManager::getInstance()->getGrid()
+ grid
+ ".xml")
);
}
// static
std::string LLFavoritesOrderStorage::getStoredFavoritesFilename()
{
return getStoredFavoritesFilename(LLGridManager::getInstance()->getGrid());
}
// static
void LLFavoritesOrderStorage::destroyClass()
{
@ -1602,6 +1608,64 @@ void LLFavoritesOrderStorage::load()
}
}
// static
void LLFavoritesOrderStorage::removeFavoritesRecordOfUser(const std::string &user, const std::string &grid)
{
std::string filename = getStoredFavoritesFilename(grid);
if (!filename.empty())
{
LLSD fav_llsd;
llifstream file;
file.open(filename.c_str());
if (file.is_open())
{
LLSDSerialize::fromXML(fav_llsd, file);
file.close();
// Note : use the "John Doe" and not the "john.doe" version of the name.
// See saveFavoritesSLURLs() here above for the reason why.
if (fav_llsd.has(user))
{
LLSD user_llsd = fav_llsd[user];
if ((user_llsd.beginArray() != user_llsd.endArray()) && user_llsd.beginArray()->has("id"))
{
for (LLSD::array_iterator iter = user_llsd.beginArray(); iter != user_llsd.endArray(); ++iter)
{
LLSD value;
value["id"] = iter->get("id").asUUID();
iter->assign(value);
}
fav_llsd[user] = user_llsd;
llofstream file;
file.open(filename.c_str());
if (file.is_open())
{
LLSDSerialize::toPrettyXML(fav_llsd, file);
file.close();
}
}
else
{
LL_INFOS("FavoritesBar") << "Removed favorites for " << user << LL_ENDL;
fav_llsd.erase(user);
}
}
llofstream out_file;
out_file.open(filename.c_str());
if (out_file.is_open())
{
LLSDSerialize::toPrettyXML(fav_llsd, out_file);
LL_INFOS("FavoritesBar") << "saved favorites to '" << filename << "' "
<< LL_ENDL;
out_file.close();
}
}
}
}
// static
void LLFavoritesOrderStorage::removeFavoritesRecordOfUser()
{
std::string filename = getStoredFavoritesFilename();

View File

@ -208,9 +208,15 @@ public:
* @see cleanup()
*/
static void destroyClass();
static std::string getStoredFavoritesFilename(const std::string &grid);
static std::string getStoredFavoritesFilename();
static std::string getSavedOrderFileName();
// Remove record of specified user's favorites from file on disk.
static void removeFavoritesRecordOfUser(const std::string &user, const std::string &grid);
// Remove record of current user's favorites from file on disk.
static void removeFavoritesRecordOfUser();
BOOL saveFavoritesRecord(bool pref_changed = false);
void showFavoritesOnLoginChanged(BOOL show);
@ -232,9 +238,6 @@ private:
void load();
// Remove record of current user's favorites from file on disk.
void removeFavoritesRecordOfUser();
void onLandmarkLoaded(const LLUUID& asset_id, class LLLandmark* landmark);
void storeFavoriteSLURL(const LLUUID& asset_id, std::string& slurl);

View File

@ -0,0 +1,154 @@
/**
* @file llfloaterforgetuser.cpp
* @brief LLFloaterForgetUser class definition.
*
* $LicenseInfo:firstyear=2019&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2019, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "llfloaterforgetuser.h"
#include "llcheckboxctrl.h"
#include "llfavoritesbar.h"
#include "llpanellogin.h" // for helper function getUserName() and to repopulate list if nessesary
#include "llscrolllistctrl.h"
#include "llsecapi.h"
#include "llviewernetwork.h"
LLFloaterForgetUser::LLFloaterForgetUser(const LLSD &key)
: LLFloater("floater_forget_user"),
mLoginPanelDirty(false)
{
}
LLFloaterForgetUser::~LLFloaterForgetUser()
{
if (mLoginPanelDirty)
{
LLPanelLogin::resetFields();
}
}
BOOL LLFloaterForgetUser::postBuild()
{
// Note, storage works per grid, watever is selected currently in login screen or logged in.
// Since login screen can change grid, store the value.
mGrid = LLGridManager::getInstance()->getGrid();
LLScrollListCtrl *scroll_list = getChild<LLScrollListCtrl>("user_list");
if (gSecAPIHandler->hasCredentialMap("login_list", mGrid))
{
LLSecAPIHandler::credential_map_t credencials;
gSecAPIHandler->loadCredentialMap("login_list", mGrid, credencials);
LLSecAPIHandler::credential_map_t::iterator cr_iter = credencials.begin();
LLSecAPIHandler::credential_map_t::iterator cr_end = credencials.end();
while (cr_iter != cr_end)
{
if (cr_iter->second.notNull()) // basic safety
{
LLScrollListItem::Params item_params;
item_params.value(cr_iter->first);
item_params.columns.add()
.value(LLPanelLogin::getUserName(cr_iter->second))
.column("user")
.font(LLFontGL::getFontSansSerifSmall());
scroll_list->addRow(item_params, ADD_BOTTOM);
}
cr_iter++;
}
scroll_list->selectFirstItem();
}
else
{
LLPointer<LLCredential> cred = gSecAPIHandler->loadCredential(mGrid);
if (cred.notNull())
{
LLScrollListItem::Params item_params;
item_params.value(cred->userID());
item_params.columns.add()
.value(LLPanelLogin::getUserName(cred))
.column("user")
.font(LLFontGL::getFontSansSerifSmall());
scroll_list->addRow(item_params, ADD_BOTTOM);
scroll_list->selectFirstItem();
}
}
bool enable_button = scroll_list->getFirstSelectedIndex() != -1;
getChild<LLView>("delete_data")->setEnabled(enable_button);
LLButton *button = getChild<LLButton>("forget");
button->setEnabled(enable_button);
button->setCommitCallback(boost::bind(&LLFloaterForgetUser::onForgetClicked, this));
return TRUE;
}
void LLFloaterForgetUser::onForgetClicked()
{
mLoginPanelDirty = true;
LLScrollListCtrl *scroll_list = getChild<LLScrollListCtrl>("user_list");
std::string user_key = scroll_list->getSelectedValue();
// remove creds
gSecAPIHandler->removeFromCredentialMap("login_list", mGrid, user_key);
LLPointer<LLCredential> cred = gSecAPIHandler->loadCredential(mGrid);
if (cred.notNull() && cred->userID() == user_key)
{
gSecAPIHandler->deleteCredential(cred);
}
// Clean data
LLCheckBoxCtrl *chk_box = getChild<LLCheckBoxCtrl>("delete_data");
BOOL delete_data = chk_box->getValue();
if (delete_data)
{
// key is edentical to one we use for name of user's folder
std::string user_path = gDirUtilp->getOSUserAppDir() + gDirUtilp->getDirDelimiter() + user_key;
gDirUtilp->deleteDirAndContents(user_path);
// Clean favorites, label is edentical to username
LLFavoritesOrderStorage::removeFavoritesRecordOfUser(scroll_list->getSelectedItemLabel(), mGrid);
// Note: we do not clean user-related files from cache because there are id dependent (inventory)
// files and cache has separate cleaning mechanism either way.
// Also this only cleans user from current grid, not all of them.
}
// Update UI
scroll_list->deleteSelectedItems();
scroll_list->selectFirstItem();
if (scroll_list->getFirstSelectedIndex() == -1)
{
LLButton *button = getChild<LLButton>("forget");
button->setEnabled(false);
chk_box->setEnabled(false);
}
}

View File

@ -0,0 +1,46 @@
/**
* @file llfloaterforgetuser.h
* @brief LLFloaterForgetUser class declaration.
*
* $LicenseInfo:firstyear=2019&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2019, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_LLFLOATERFORGETUSER_H
#define LL_LLFLOATERFORGETUSER_H
#include "llfloater.h"
class LLFloaterForgetUser : public LLFloater
{
public:
LLFloaterForgetUser(const LLSD &key);
~LLFloaterForgetUser();
BOOL postBuild();
void onForgetClicked();
private:
bool mLoginPanelDirty;
std::string mGrid;
};
#endif

View File

@ -419,6 +419,7 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
mCommitCallbackRegistrar.add("Pref.TranslationSettings", boost::bind(&LLFloaterPreference::onClickTranslationSettings, this));
mCommitCallbackRegistrar.add("Pref.AutoReplace", boost::bind(&LLFloaterPreference::onClickAutoReplace, this));
mCommitCallbackRegistrar.add("Pref.PermsDefault", boost::bind(&LLFloaterPreference::onClickPermsDefault, this));
mCommitCallbackRegistrar.add("Pref.RememberedUsernames", boost::bind(&LLFloaterPreference::onClickRememberedUsernames, this));
mCommitCallbackRegistrar.add("Pref.SpellChecker", boost::bind(&LLFloaterPreference::onClickSpellChecker, this));
mCommitCallbackRegistrar.add("Pref.Advanced", boost::bind(&LLFloaterPreference::onClickAdvanced, this));
@ -2256,6 +2257,11 @@ void LLFloaterPreference::onClickPermsDefault()
LLFloaterReg::showInstance("perms_default");
}
void LLFloaterPreference::onClickRememberedUsernames()
{
LLFloaterReg::showInstance("forget_username");
}
void LLFloaterPreference::onDeleteTranscripts()
{
LLSD args;

View File

@ -181,6 +181,7 @@ public:
void onClickProxySettings();
void onClickTranslationSettings();
void onClickPermsDefault();
void onClickRememberedUsernames();
void onClickAutoReplace();
void onClickSpellChecker();
void onClickRenderExceptions();

View File

@ -139,8 +139,11 @@ LLPointer<LLCredential> LLLoginHandler::initializeLoginInfo()
// so try to load it from the UserLoginInfo
result = loadSavedUserLoginInfo();
if (result.isNull())
{
result = gSecAPIHandler->loadCredential(LLGridManager::getInstance()->getGrid());
{
// Since legacy viewer store login info one per grid, newer viewers have to
// reuse same information to remember last user and for compatibility,
// but otherwise login info is stored in separate map in gSecAPIHandler
result = gSecAPIHandler->loadCredential(LLGridManager::getInstance()->getGrid());
}
return result;

View File

@ -77,6 +77,60 @@ LLPanelLogin *LLPanelLogin::sInstance = NULL;
BOOL LLPanelLogin::sCapslockDidNotification = FALSE;
BOOL LLPanelLogin::sCredentialSet = FALSE;
// Helper functions
LLPointer<LLCredential> load_user_credentials(std::string &user_key)
{
if (gSecAPIHandler->hasCredentialMap("login_list", LLGridManager::getInstance()->getGrid()))
{
// user_key should be of "name Resident" format
return gSecAPIHandler->loadFromCredentialMap("login_list", LLGridManager::getInstance()->getGrid(), user_key);
}
else
{
// legacy (or legacy^2, since it also tries to load from settings)
return gSecAPIHandler->loadCredential(LLGridManager::getInstance()->getGrid());
}
}
// keys are lower case to be case insensitive so they are not always
// identical to names which retain user input, like:
// "AwEsOmE Resident" -> "awesome_resident"
std::string get_user_key_from_name(const std::string &username)
{
std::string key = username;
LLStringUtil::trim(key);
LLStringUtil::toLower(key);
if (!LLGridManager::getInstance()->isSystemGrid())
{
size_t separator_index = username.find_first_of(" ");
if (separator_index == username.npos)
{
// CRED_IDENTIFIER_TYPE_ACCOUNT
return key;
}
}
// CRED_IDENTIFIER_TYPE_AGENT
size_t separator_index = username.find_first_of(" ._");
std::string first = username.substr(0, separator_index);
std::string last;
if (separator_index != username.npos)
{
last = username.substr(separator_index + 1, username.npos);
LLStringUtil::trim(last);
}
else
{
// ...on Linden grids, single username users as considered to have
// last name "Resident"
// *TODO: Make login.cgi support "account_name" like above
last = "resident";
}
key = first + "_" + last;
return key;
}
class LLLoginLocationAutoHandler : public LLCommandHandler
{
public:
@ -168,6 +222,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
mCallback(callback),
mCallbackData(cb_data),
mListener(new LLPanelLoginListener(this)),
mFirstLoginThisInstall(gSavedSettings.getBOOL("FirstLoginThisInstall")),
mUsernameLength(0),
mPasswordLength(0),
mLocationLength(0),
@ -186,7 +241,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
login_holder->addChild(this);
}
if (gSavedSettings.getBOOL("FirstLoginThisInstall"))
if (mFirstLoginThisInstall)
{
buildFromFile( "panel_login_first.xml");
}
@ -206,35 +261,39 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
sendChildToBack(getChildView("forgot_password_text"));
sendChildToBack(getChildView("sign_up_text"));
LLComboBox* favorites_combo = getChild<LLComboBox>("start_location_combo");
updateLocationSelectorsVisibility(); // separate so that it can be called from preferences
favorites_combo->setReturnCallback(boost::bind(&LLPanelLogin::onClickConnect, this));
favorites_combo->setFocusLostCallback(boost::bind(&LLPanelLogin::onLocationSLURL, this));
LLComboBox* server_choice_combo = getChild<LLComboBox>("server_combo");
server_choice_combo->setCommitCallback(boost::bind(&LLPanelLogin::onSelectServer, this));
// Load all of the grids, sorted, and then add a bar and the current grid at the top
server_choice_combo->removeall();
std::string current_grid = LLGridManager::getInstance()->getGrid();
if (!mFirstLoginThisInstall)
{
LLComboBox* favorites_combo = getChild<LLComboBox>("start_location_combo");
updateLocationSelectorsVisibility(); // separate so that it can be called from preferences
favorites_combo->setReturnCallback(boost::bind(&LLPanelLogin::onClickConnect, this));
favorites_combo->setFocusLostCallback(boost::bind(&LLPanelLogin::onLocationSLURL, this));
std::string current_grid = LLGridManager::getInstance()->getGrid();
std::map<std::string, std::string> known_grids = LLGridManager::getInstance()->getKnownGrids();
for (std::map<std::string, std::string>::iterator grid_choice = known_grids.begin();
grid_choice != known_grids.end();
grid_choice++)
{
if (!grid_choice->first.empty() && current_grid != grid_choice->first)
{
LL_DEBUGS("AppInit")<<"adding "<<grid_choice->first<<LL_ENDL;
server_choice_combo->add(grid_choice->second, grid_choice->first);
}
}
server_choice_combo->sortByName();
LL_DEBUGS("AppInit")<<"adding current "<<current_grid<<LL_ENDL;
server_choice_combo->add(LLGridManager::getInstance()->getGridLabel(),
current_grid,
ADD_TOP);
server_choice_combo->selectFirstItem();
LLComboBox* server_choice_combo = getChild<LLComboBox>("server_combo");
server_choice_combo->setCommitCallback(boost::bind(&LLPanelLogin::onSelectServer, this));
// Load all of the grids, sorted, and then add a bar and the current grid at the top
server_choice_combo->removeall();
std::map<std::string, std::string> known_grids = LLGridManager::getInstance()->getKnownGrids();
for (std::map<std::string, std::string>::iterator grid_choice = known_grids.begin();
grid_choice != known_grids.end();
grid_choice++)
{
if (!grid_choice->first.empty() && current_grid != grid_choice->first)
{
LL_DEBUGS("AppInit") << "adding " << grid_choice->first << LL_ENDL;
server_choice_combo->add(grid_choice->second, grid_choice->first);
}
}
server_choice_combo->sortByName();
LL_DEBUGS("AppInit") << "adding current " << current_grid << LL_ENDL;
server_choice_combo->add(LLGridManager::getInstance()->getGridLabel(),
current_grid,
ADD_TOP);
server_choice_combo->selectFirstItem();
}
LLSLURL start_slurl(LLStartUp::getStartSLURL());
// The StartSLURL might have been set either by an explicit command-line
@ -297,14 +356,30 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
loadLoginPage();
LLComboBox* username_combo(getChild<LLComboBox>("username_combo"));
username_combo->setTextChangedCallback(boost::bind(&LLPanelLogin::addFavoritesToStartLocation, this));
username_combo->setTextChangedCallback(boost::bind(&LLPanelLogin::onUserNameTextEnty, this));
// STEAM-14: When user presses Enter with this field in focus, initiate login
username_combo->setCommitCallback(boost::bind(&LLPanelLogin::onClickConnect, this));
username_combo->setCommitCallback(boost::bind(&LLPanelLogin::onUserListCommit, this));
username_combo->setReturnCallback(boost::bind(&LLPanelLogin::onClickConnect, this));
username_combo->setKeystrokeOnEsc(TRUE);
if (!mFirstLoginThisInstall)
{
LLCheckBoxCtrl* remember_name = getChild<LLCheckBoxCtrl>("remember_name");
remember_name->setCommitCallback(boost::bind(&LLPanelLogin::onRememberUserCheck, this));
}
}
void LLPanelLogin::addFavoritesToStartLocation()
{
if (mFirstLoginThisInstall)
{
// first login panel has no favorites, just update name length and buttons
std::string user_defined_name = getChild<LLComboBox>("username_combo")->getSimple();
mUsernameLength = user_defined_name.length();
updateLoginButtons();
return;
}
// Clear the combo.
LLComboBox* combo = getChild<LLComboBox>("start_location_combo");
if (!combo) return;
@ -316,14 +391,14 @@ void LLPanelLogin::addFavoritesToStartLocation()
// Load favorites into the combo.
std::string user_defined_name = getChild<LLComboBox>("username_combo")->getSimple();
LLStringUtil::trim(user_defined_name);
LLStringUtil::toLower(user_defined_name);
std::replace(user_defined_name.begin(), user_defined_name.end(), '.', ' ');
std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites_" + LLGridManager::getInstance()->getGrid() + ".xml");
std::string old_filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites.xml");
mUsernameLength = user_defined_name.length();
updateLoginButtons();
std::string::size_type index = user_defined_name.find(' ');
std::string::size_type index = user_defined_name.find_first_of(" ._");
if (index != std::string::npos)
{
std::string username = user_defined_name.substr(0, index);
@ -332,6 +407,10 @@ void LLPanelLogin::addFavoritesToStartLocation()
{
user_defined_name = username;
}
else
{
user_defined_name = username + " " + lastname;
}
}
LLSD fav_llsd;
@ -442,24 +521,6 @@ void LLPanelLogin::giveFocus()
}
}
// static
void LLPanelLogin::showLoginWidgets()
{
if (sInstance)
{
// *NOTE: Mani - This may or may not be obselete code.
// It seems to be part of the defunct? reg-in-client project.
sInstance->getChildView("login_widgets")->setVisible( true);
LLMediaCtrl* web_browser = sInstance->getChild<LLMediaCtrl>("login_html");
// *TODO: Append all the usual login parameters, like first_login=Y etc.
std::string splash_screen_url = LLGridManager::getInstance()->getLoginPage();
web_browser->navigateTo( splash_screen_url, "text/html" );
LLUICtrl* username_combo = sInstance->getChild<LLUICtrl>("username_combo");
username_combo->setFocus(TRUE);
}
}
// static
void LLPanelLogin::show(const LLRect &rect,
void (*callback)(S32 option, void* user_data),
@ -480,9 +541,55 @@ void LLPanelLogin::show(const LLRect &rect,
gFocusMgr.setDefaultKeyboardFocus(sInstance);
}
//static
void LLPanelLogin::populateFields(LLPointer<LLCredential> credential, bool remember_user, bool remember_psswrd)
{
if (!sInstance)
{
LL_WARNS() << "Attempted fillFields with no login view shown" << LL_ENDL;
return;
}
LLUICtrl* remember_check = sInstance->getChild<LLUICtrl>("remember_check");
remember_check->setValue(remember_psswrd);
if (sInstance->mFirstLoginThisInstall)
{
// no list to populate
setFields(credential, remember_psswrd);
}
else
{
sInstance->getChild<LLUICtrl>("remember_name")->setValue(remember_user);
sInstance->populateUserList(credential, remember_psswrd);
remember_check->setEnabled(remember_user);
}
}
//static
void LLPanelLogin::resetFields()
{
if (!sInstance)
{
// class not existing at this point might happen since this
// function is used to reset list in case of changes by external sources
return;
}
if (sInstance->mFirstLoginThisInstall)
{
// no list to populate
LL_WARNS() << "Shouldn't happen, user should have no ability to modify list on first install" << LL_ENDL;
}
else
{
LLUICtrl* remember_check = sInstance->getChild<LLUICtrl>("remember_check");
bool remember_psswrd = remember_check->getValue();
LLPointer<LLCredential> cred = gSecAPIHandler->loadCredential(LLGridManager::getInstance()->getGrid());
sInstance->populateUserList(cred, remember_psswrd);
}
}
// static
void LLPanelLogin::setFields(LLPointer<LLCredential> credential,
BOOL remember)
bool remember_psswrd)
{
if (!sInstance)
{
@ -492,13 +599,15 @@ void LLPanelLogin::setFields(LLPointer<LLCredential> credential,
sCredentialSet = TRUE;
LL_INFOS("Credentials") << "Setting login fields to " << *credential << LL_ENDL;
LLSD identifier = credential->getIdentifier();
if((std::string)identifier["type"] == "agent")
LLSD identifier = credential.notNull() ? credential->getIdentifier() : LLSD();
if(identifier.has("type") && (std::string)identifier["type"] == "agent")
{
// not nessesary for panel_login.xml, needed for panel_login_first.xml
std::string firstname = identifier["first_name"].asString();
std::string lastname = identifier["last_name"].asString();
std::string login_id = firstname;
if (!lastname.empty() && lastname != "Resident")
if (!lastname.empty() && lastname != "Resident" && lastname != "resident")
{
// support traditional First Last name SLURLs
login_id += " ";
@ -506,22 +615,23 @@ void LLPanelLogin::setFields(LLPointer<LLCredential> credential,
}
sInstance->getChild<LLComboBox>("username_combo")->setLabel(login_id);
}
else if((std::string)identifier["type"] == "account")
else if(identifier.has("type") && (std::string)identifier["type"] == "account")
{
sInstance->getChild<LLComboBox>("username_combo")->setLabel((std::string)identifier["account_name"]);
}
else
{
sInstance->getChild<LLComboBox>("username_combo")->setLabel(std::string());
sInstance->getChild<LLComboBox>("username_combo")->setLabel(std::string());
}
sInstance->addFavoritesToStartLocation();
// if the password exists in the credential, set the password field with
// a filler to get some stars
LLSD authenticator = credential->getAuthenticator();
LLSD authenticator = credential.notNull() ? credential->getAuthenticator() : LLSD();
LL_INFOS("Credentials") << "Setting authenticator field " << authenticator["type"].asString() << LL_ENDL;
if(authenticator.isMap() &&
authenticator.has("secret") &&
(authenticator["secret"].asString().size() > 0) && remember)
(authenticator["secret"].asString().size() > 0) && remember_psswrd)
{
// This is a MD5 hex digest of a password.
@ -537,36 +647,25 @@ void LLPanelLogin::setFields(LLPointer<LLCredential> credential,
{
sInstance->getChild<LLUICtrl>("password_edit")->setValue(std::string());
}
sInstance->getChild<LLUICtrl>("remember_check")->setValue(remember);
}
// static
void LLPanelLogin::getFields(LLPointer<LLCredential>& credential,
BOOL& remember)
bool& remember_user,
bool& remember_psswrd)
{
if (!sInstance)
{
LL_WARNS() << "Attempted getFields with no login view shown" << LL_ENDL;
return;
}
// load the credential so we can pass back the stored password or hash if the user did
// not modify the password field.
credential = gSecAPIHandler->loadCredential(LLGridManager::getInstance()->getGrid());
LLSD identifier = LLSD::emptyMap();
LLSD authenticator = LLSD::emptyMap();
if(credential.notNull())
{
authenticator = credential->getAuthenticator();
}
std::string username = sInstance->getChild<LLUICtrl>("username_combo")->getValue().asString();
LLStringUtil::trim(username);
std::string username = sInstance->getChild<LLComboBox>("username_combo")->getValue().asString();
std::string password = sInstance->getChild<LLUICtrl>("password_edit")->getValue().asString();
LLStringUtil::trim(username);
LL_INFOS("Credentials", "Authentication") << "retrieving username:" << username << LL_ENDL;
// determine if the username is a first/last form or not.
@ -586,6 +685,14 @@ void LLPanelLogin::getFields(LLPointer<LLCredential>& credential,
authenticator["type"] = CRED_AUTHENTICATOR_TYPE_CLEAR;
authenticator["secret"] = password;
}
else
{
credential = load_user_credentials(username);
if (credential.notNull())
{
authenticator = credential->getAuthenticator();
}
}
}
else
{
@ -597,7 +704,7 @@ void LLPanelLogin::getFields(LLPointer<LLCredential>& credential,
if (separator_index != username.npos)
{
last = username.substr(separator_index+1, username.npos);
LLStringUtil::trim(last);
LLStringUtil::trim(last);
}
else
{
@ -625,10 +732,28 @@ void LLPanelLogin::getFields(LLPointer<LLCredential>& credential,
pass.hex_digest(md5pass);
authenticator["secret"] = md5pass;
}
else
{
std::string key = first + "_" + last;
LLStringUtil::toLower(key);
credential = load_user_credentials(key);
if (credential.notNull())
{
authenticator = credential->getAuthenticator();
}
}
}
}
credential = gSecAPIHandler->createCredential(LLGridManager::getInstance()->getGrid(), identifier, authenticator);
remember = sInstance->getChild<LLUICtrl>("remember_check")->getValue();
remember_psswrd = sInstance->getChild<LLUICtrl>("remember_check")->getValue();
if (!sInstance->mFirstLoginThisInstall)
{
remember_user = sInstance->getChild<LLUICtrl>("remember_name")->getValue();
}
else
{
remember_user = true;
}
}
@ -898,8 +1023,8 @@ void LLPanelLogin::onClickConnect(void *)
{
sCredentialSet = FALSE;
LLPointer<LLCredential> cred;
BOOL remember;
getFields(cred, remember);
bool remember_1, remember_2;
getFields(cred, remember_1, remember_2);
std::string identifier_type;
cred->identifierType(identifier_type);
LLSD allowed_credential_types;
@ -952,6 +1077,57 @@ void LLPanelLogin::onClickSignUp(void*)
}
}
// static
void LLPanelLogin::onUserNameTextEnty(void*)
{
sInstance->mPasswordModified = true;
sInstance->getChild<LLUICtrl>("password_edit")->setValue(std::string());
sInstance->addFavoritesToStartLocation(); //will call updateLoginButtons()
}
// static
void LLPanelLogin::onUserListCommit(void*)
{
if (sInstance)
{
LLComboBox* username_combo(sInstance->getChild<LLComboBox>("username_combo"));
static S32 ind = -1;
if (ind != username_combo->getCurrentIndex())
{
std::string user_key = username_combo->getSelectedValue();
LLPointer<LLCredential> cred = gSecAPIHandler->loadFromCredentialMap("login_list", LLGridManager::getInstance()->getGrid(), user_key);
bool remember_psswrd = sInstance->getChild<LLUICtrl>("remember_check")->getValue();
setFields(cred, remember_psswrd);
sInstance->mPasswordModified = false;
}
else
{
std::string pass = sInstance->getChild<LLUICtrl>("password_edit")->getValue().asString();
if (pass.empty())
{
sInstance->giveFocus();
}
else
{
onClickConnect(NULL);
}
}
}
}
// static
void LLPanelLogin::onRememberUserCheck(void*)
{
if (sInstance)
{
LLCheckBoxCtrl* remember_name(sInstance->getChild<LLCheckBoxCtrl>("remember_name"));
LLCheckBoxCtrl* remember_psswrd(sInstance->getChild<LLCheckBoxCtrl>("remember_check"));
bool remember = remember_name->getValue().asBoolean();
remember_psswrd->setEnabled(remember);
}
}
// static
void LLPanelLogin::onPassKey(LLLineEditor* caller, void* user_data)
{
@ -979,9 +1155,11 @@ void LLPanelLogin::updateServer()
// for that grid and set them to the UI.
if(!sInstance->areCredentialFieldsDirty())
{
LLPointer<LLCredential> credential = gSecAPIHandler->loadCredential(LLGridManager::getInstance()->getGrid());
bool remember = sInstance->getChild<LLUICtrl>("remember_check")->getValue();
sInstance->setFields(credential, remember);
// populate dropbox and setFields
bool remember_psswrd = sInstance->getChild<LLUICtrl>("remember_check")->getValue();
// Note: following call is related to initializeLoginInfo()
LLPointer<LLCredential> credential = gSecAPIHandler->loadCredential(LLGridManager::getInstance()->getGrid());
sInstance->populateUserList(credential, remember_psswrd);
}
// update the login panel links
@ -1011,14 +1189,63 @@ void LLPanelLogin::updateLoginButtons()
LLButton* login_btn = getChild<LLButton>("connect_btn");
login_btn->setEnabled(mUsernameLength != 0 && mPasswordLength != 0);
if (!mFirstLoginThisInstall)
{
LLComboBox* user_combo = getChild<LLComboBox>("username_combo");
LLCheckBoxCtrl* remember_name = getChild<LLCheckBoxCtrl>("remember_name");
remember_name->setEnabled(user_combo->getCurrentIndex() == -1);
}
}
void LLPanelLogin::populateUserList(LLPointer<LLCredential> credential, bool remember_psswrd)
{
LLComboBox* user_combo = getChild<LLComboBox>("username_combo");
user_combo->removeall();
user_combo->clear();
if (gSecAPIHandler->hasCredentialMap("login_list", LLGridManager::getInstance()->getGrid()))
{
LLSecAPIHandler::credential_map_t credencials;
gSecAPIHandler->loadCredentialMap("login_list", LLGridManager::getInstance()->getGrid(), credencials);
LLSecAPIHandler::credential_map_t::iterator cr_iter = credencials.begin();
LLSecAPIHandler::credential_map_t::iterator cr_end = credencials.end();
while (cr_iter != cr_end)
{
if (cr_iter->second.notNull()) // basic safety in case of future changes
{
// cr_iter->first == user_id , to be able to be find it in case we select it
user_combo->add(LLPanelLogin::getUserName(cr_iter->second), cr_iter->first, ADD_BOTTOM, TRUE);
}
cr_iter++;
}
if (credential.isNull() || !user_combo->setSelectedByValue(LLSD(credential->userID()), true))
{
// selection failed, just deselect whatever might be selected
user_combo->setValue(std::string());
}
else
{
setFields(credential, remember_psswrd);
}
}
else
{
if (credential.notNull())
{
user_combo->add(LLPanelLogin::getUserName(credential), credential->userID(), ADD_BOTTOM, TRUE);
setFields(credential, remember_psswrd);
}
}
}
void LLPanelLogin::onSelectServer()
{
// The user twiddled with the grid choice ui.
// apply the selection to the grid setting.
LLPointer<LLCredential> credential;
LLComboBox* server_combo = getChild<LLComboBox>("server_combo");
LLSD server_combo_val = server_combo->getSelectedValue();
LL_INFOS("AppInit") << "grid "<<server_combo_val.asString()<< LL_ENDL;
@ -1077,3 +1304,34 @@ bool LLPanelLogin::getShowFavorites()
{
return gSavedPerAccountSettings.getBOOL("ShowFavoritesOnLogin");
}
// static
std::string LLPanelLogin::getUserName(LLPointer<LLCredential> &cred)
{
if (cred.isNull())
{
return "unknown";
}
const LLSD &ident = cred->getIdentifier();
if (!ident.isMap())
{
return "unknown";
}
else if ((std::string)ident["type"] == "agent")
{
std::string second_name = ident["last_name"];
if (second_name == "resident" || second_name == "Resident")
{
return (std::string)ident["first_name"];
}
return (std::string)ident["first_name"] + " " + (std::string)ident["last_name"];
}
else if ((std::string)ident["type"] == "account")
{
return LLCacheName::cleanFullName((std::string)ident["account_name"]);
}
return "unknown";
}

View File

@ -55,9 +55,9 @@ public:
void (*callback)(S32 option, void* user_data),
void* callback_data);
static void setFields(LLPointer<LLCredential> credential, BOOL remember);
static void getFields(LLPointer<LLCredential>& credential, BOOL& remember);
static void populateFields(LLPointer<LLCredential> credential, bool remember_user, bool remember_psswrd);
static void resetFields();
static void getFields(LLPointer<LLCredential>& credential, bool& remember_user, bool& remember_psswrd);
static BOOL isCredentialSet() { return sCredentialSet; }
@ -72,8 +72,6 @@ public:
void setSiteIsAlive( bool alive );
void showLoginWidgets();
static void loadLoginPage();
static void giveFocus();
static void setAlwaysRefresh(bool refresh);
@ -88,6 +86,9 @@ public:
// called from prefs when initializing panel
static bool getShowFavorites();
// extract name from cred in a format apropriate for username field
static std::string getUserName(LLPointer<LLCredential> &cred);
private:
friend class LLPanelLoginListener;
void addFavoritesToStartLocation();
@ -95,11 +96,16 @@ private:
void onSelectServer();
void onLocationSLURL();
static void setFields(LLPointer<LLCredential> credential, bool remember_psswrd);
static void onClickConnect(void*);
static void onClickNewAccount(void*);
static void onClickVersion(void*);
static void onClickForgotPassword(void*);
static void onClickSignUp(void*);
static void onUserNameTextEnty(void*);
static void onUserListCommit(void*);
static void onRememberUserCheck(void*);
static void onPassKey(LLLineEditor* caller, void* user_data);
static void updateServerCombo();
@ -107,6 +113,7 @@ private:
boost::scoped_ptr<LLPanelLoginListener> mListener;
void updateLoginButtons();
void populateUserList(LLPointer<LLCredential> credential, bool remember_psswrd);
void (*mCallback)(S32 option, void *userdata);
void* mCallbackData;

View File

@ -464,7 +464,19 @@ public:
// delete a protected data item from the store
virtual void deleteProtectedData(const std::string& data_type,
const std::string& data_id)=0;
// persist data in a protected store's map
virtual void addToProtectedMap(const std::string& data_type,
const std::string& data_id,
const std::string& map_elem,
const LLSD& data)=0;
// remove data from protected store's map
virtual void removeFromProtectedMap(const std::string& data_type,
const std::string& data_id,
const std::string& map_elem)=0;
public:
virtual LLPointer<LLCredential> createCredential(const std::string& grid,
const LLSD& identifier,
const LLSD& authenticator)=0;
@ -474,6 +486,38 @@ public:
virtual void saveCredential(LLPointer<LLCredential> cred, bool save_authenticator)=0;
virtual void deleteCredential(LLPointer<LLCredential> cred)=0;
// has map of credentials declared as specific storage
virtual bool hasCredentialMap(const std::string& storage,
const std::string& grid)=0;
// load map of credentials from specific storage
typedef std::map<std::string, LLPointer<LLCredential> > credential_map_t;
virtual void loadCredentialMap(const std::string& storage,
const std::string& grid,
credential_map_t& credential_map)=0;
// load single username from map of credentials from specific storage
virtual LLPointer<LLCredential> loadFromCredentialMap(const std::string& storage,
const std::string& grid,
const std::string& userid)=0;
// add item to map of credentials from specific storage
virtual void addToCredentialMap(const std::string& storage,
LLPointer<LLCredential> cred,
bool save_authenticator)=0;
// remove item from map of credentials from specific storage
virtual void removeFromCredentialMap(const std::string& storage,
LLPointer<LLCredential> cred)=0;
// remove item from map of credentials from specific storage
virtual void removeFromCredentialMap(const std::string& storage,
const std::string& grid,
const std::string& userid)=0;
virtual void removeCredentialMap(const std::string& storage,
const std::string& grid)=0;
};

View File

@ -52,6 +52,7 @@
#include "llmachineid.h"
static const std::string DEFAULT_CREDENTIAL_STORAGE = "credential";
// 128 bits of salt data...
#define STORE_SALT_SIZE 16
@ -1533,6 +1534,38 @@ void LLSecAPIBasicHandler::setProtectedData(const std::string& data_type,
mProtectedDataMap[data_type][data_id] = data;
}
// persist data in a protected store's map
void LLSecAPIBasicHandler::addToProtectedMap(const std::string& data_type,
const std::string& data_id,
const std::string& map_elem,
const LLSD& data)
{
if (!mProtectedDataMap.has(data_type) || !mProtectedDataMap[data_type].isMap()) {
mProtectedDataMap[data_type] = LLSD::emptyMap();
}
if (!mProtectedDataMap[data_type].has(data_id) || !mProtectedDataMap[data_type][data_id].isMap()) {
mProtectedDataMap[data_type][data_id] = LLSD::emptyMap();
}
mProtectedDataMap[data_type][data_id][map_elem] = data;
}
// remove data from protected store's map
void LLSecAPIBasicHandler::removeFromProtectedMap(const std::string& data_type,
const std::string& data_id,
const std::string& map_elem)
{
if (mProtectedDataMap.has(data_type) &&
mProtectedDataMap[data_type].isMap() &&
mProtectedDataMap[data_type].has(data_id) &&
mProtectedDataMap[data_type][data_id].isMap() &&
mProtectedDataMap[data_type][data_id].has(map_elem))
{
mProtectedDataMap[data_type][data_id].erase(map_elem);
}
}
//
// Create a credential object from an identifier and authenticator. credentials are
// per grid.
@ -1545,10 +1578,10 @@ LLPointer<LLCredential> LLSecAPIBasicHandler::createCredential(const std::string
return result;
}
// Load a credential from the credential store, given the grid
// Load a credential from default credential store, given the grid
LLPointer<LLCredential> LLSecAPIBasicHandler::loadCredential(const std::string& grid)
{
LLSD credential = getProtectedData("credential", grid);
LLSD credential = getProtectedData(DEFAULT_CREDENTIAL_STORAGE, grid);
LLPointer<LLSecAPIBasicCredential> result = new LLSecAPIBasicCredential(grid);
if(credential.isMap() &&
credential.has("identifier"))
@ -1603,7 +1636,7 @@ void LLSecAPIBasicHandler::saveCredential(LLPointer<LLCredential> cred, bool sav
credential["authenticator"] = cred->getAuthenticator();
}
LL_DEBUGS("SECAPI") << "Saving Credential " << cred->getGrid() << ":" << cred->userID() << " " << save_authenticator << LL_ENDL;
setProtectedData("credential", cred->getGrid(), credential);
setProtectedData(DEFAULT_CREDENTIAL_STORAGE, cred->getGrid(), credential);
//*TODO: If we're saving Agni credentials, should we write the
// credentials to the legacy password.dat/etc?
_writeProtectedData();
@ -1613,11 +1646,137 @@ void LLSecAPIBasicHandler::saveCredential(LLPointer<LLCredential> cred, bool sav
void LLSecAPIBasicHandler::deleteCredential(LLPointer<LLCredential> cred)
{
LLSD undefVal;
deleteProtectedData("credential", cred->getGrid());
deleteProtectedData(DEFAULT_CREDENTIAL_STORAGE, cred->getGrid());
cred->setCredentialData(undefVal, undefVal);
_writeProtectedData();
}
// has map of credentials declared as specific storage
bool LLSecAPIBasicHandler::hasCredentialMap(const std::string& storage, const std::string& grid)
{
if (storage == DEFAULT_CREDENTIAL_STORAGE)
{
LL_ERRS() << "Storing maps in default, single-items storage is not allowed" << LL_ENDL;
}
LLSD credential = getProtectedData(storage, grid);
return credential.isMap();
}
// Load map of credentials from specified credential store, given the grid
void LLSecAPIBasicHandler::loadCredentialMap(const std::string& storage, const std::string& grid, credential_map_t& credential_map)
{
if (storage == DEFAULT_CREDENTIAL_STORAGE)
{
LL_ERRS() << "Storing maps in default, single-items storage is not allowed" << LL_ENDL;
}
LLSD credential = getProtectedData(storage, grid);
if (credential.isMap())
{
LLSD::map_const_iterator crd_it = credential.beginMap();
for (; crd_it != credential.endMap(); crd_it++)
{
LLSD::String name = crd_it->first;
const LLSD &link_map = crd_it->second;
LLPointer<LLSecAPIBasicCredential> result = new LLSecAPIBasicCredential(grid);
if (link_map.has("identifier"))
{
LLSD identifier = link_map["identifier"];
LLSD authenticator;
if (link_map.has("authenticator"))
{
authenticator = link_map["authenticator"];
}
result->setCredentialData(identifier, authenticator);
}
credential_map[name] = result;
}
}
}
LLPointer<LLCredential> LLSecAPIBasicHandler::loadFromCredentialMap(const std::string& storage, const std::string& grid, const std::string& userkey)
{
if (storage == DEFAULT_CREDENTIAL_STORAGE)
{
LL_ERRS() << "Storing maps in default, single-items storage is not allowed" << LL_ENDL;
}
LLPointer<LLSecAPIBasicCredential> result = new LLSecAPIBasicCredential(grid);
LLSD credential = getProtectedData(storage, grid);
if (credential.isMap() && credential.has(userkey) && credential[userkey].has("identifier"))
{
LLSD identifier = credential[userkey]["identifier"];
LLSD authenticator;
if (credential[userkey].has("authenticator"))
{
authenticator = credential[userkey]["authenticator"];
}
result->setCredentialData(identifier, authenticator);
}
return result;
}
// add item to map of credentials from specific storage
void LLSecAPIBasicHandler::addToCredentialMap(const std::string& storage, LLPointer<LLCredential> cred, bool save_authenticator)
{
if (storage == DEFAULT_CREDENTIAL_STORAGE)
{
LL_ERRS() << "Storing maps in default, single-items storage is not allowed" << LL_ENDL;
}
std::string user_id = cred->userID();
LLSD credential = LLSD::emptyMap();
credential["identifier"] = cred->getIdentifier();
if (save_authenticator)
{
credential["authenticator"] = cred->getAuthenticator();
}
LL_DEBUGS("SECAPI") << "Saving Credential " << cred->getGrid() << ":" << cred->userID() << " " << save_authenticator << LL_ENDL;
addToProtectedMap(storage, cred->getGrid(), user_id, credential);
_writeProtectedData();
}
// remove item from map of credentials from specific storage
void LLSecAPIBasicHandler::removeFromCredentialMap(const std::string& storage, LLPointer<LLCredential> cred)
{
if (storage == DEFAULT_CREDENTIAL_STORAGE)
{
LL_ERRS() << "Storing maps in default, single-items storage is not allowed" << LL_ENDL;
}
LLSD undefVal;
removeFromProtectedMap(storage, cred->getGrid(), cred->userID());
cred->setCredentialData(undefVal, undefVal);
_writeProtectedData();
}
// remove item from map of credentials from specific storage
void LLSecAPIBasicHandler::removeFromCredentialMap(const std::string& storage, const std::string& grid, const std::string& userkey)
{
if (storage == DEFAULT_CREDENTIAL_STORAGE)
{
LL_ERRS() << "Storing maps in default, single-items storage is not allowed" << LL_ENDL;
}
LLSD undefVal;
LLPointer<LLCredential> cred = loadFromCredentialMap(storage, grid, userkey);
removeFromProtectedMap(storage, grid, userkey);
cred->setCredentialData(undefVal, undefVal);
_writeProtectedData();
}
// remove item from map of credentials from specific storage
void LLSecAPIBasicHandler::removeCredentialMap(const std::string& storage, const std::string& grid)
{
deleteProtectedData(storage, grid);
_writeProtectedData();
}
// load the legacy hash for agni, and decrypt it given the
// mac address
std::string LLSecAPIBasicHandler::_legacyLoadPassword()
@ -1656,15 +1815,18 @@ std::string LLSecAPIBasicCredential::userID() const
}
else if ((std::string)mIdentifier["type"] == "agent")
{
return (std::string)mIdentifier["first_name"] + "_" + (std::string)mIdentifier["last_name"];
std::string id = (std::string)mIdentifier["first_name"] + "_" + (std::string)mIdentifier["last_name"];
LLStringUtil::toLower(id);
return id;
}
else if ((std::string)mIdentifier["type"] == "account")
{
return (std::string)mIdentifier["account_name"];
std::string id = (std::string)mIdentifier["account_name"];
LLStringUtil::toLower(id);
return id;
}
return "unknown";
}
// return a printable user identifier

View File

@ -211,8 +211,9 @@ class LLSecAPIBasicCredential : public LLCredential
public:
LLSecAPIBasicCredential(const std::string& grid) : LLCredential(grid) {}
virtual ~LLSecAPIBasicCredential() {}
// return a value representing the user id, (could be guid, name, whatever)
virtual std::string userID() const;
// return a value representing the user id, used for server and voice
// (could be guid, name in format "name_resident", whatever)
virtual std::string userID() const;
// printible string identifying the credential.
virtual std::string asString() const;
@ -246,7 +247,10 @@ public:
// exists, it'll be loaded. If not, one will be created (but not
// persisted)
virtual LLPointer<LLCertificateStore> getCertificateStore(const std::string& store_id);
// protectedData functions technically should be pretected or private,
// they are not because of llsechandler_basic_test imlementation
// persist data in a protected store
virtual void setProtectedData(const std::string& data_type,
const std::string& data_id,
@ -259,19 +263,64 @@ public:
// delete a protected data item from the store
virtual void deleteProtectedData(const std::string& data_type,
const std::string& data_id);
// persist data in a protected store's map
virtual void addToProtectedMap(const std::string& data_type,
const std::string& data_id,
const std::string& map_elem,
const LLSD& data);
// remove data from protected store's map
virtual void removeFromProtectedMap(const std::string& data_type,
const std::string& data_id,
const std::string& map_elem);
// credential management routines
virtual LLPointer<LLCredential> createCredential(const std::string& grid,
const LLSD& identifier,
const LLSD& authenticator);
// load single credencial from default storage
virtual LLPointer<LLCredential> loadCredential(const std::string& grid);
// save credencial to default storage
virtual void saveCredential(LLPointer<LLCredential> cred, bool save_authenticator);
virtual void deleteCredential(LLPointer<LLCredential> cred);
// has map of credentials declared as specific storage
virtual bool hasCredentialMap(const std::string& storage,
const std::string& grid);
// load map of credentials from specific storage
virtual void loadCredentialMap(const std::string& storage,
const std::string& grid,
credential_map_t& credential_map);
// load single username from map of credentials from specific storage
virtual LLPointer<LLCredential> loadFromCredentialMap(const std::string& storage,
const std::string& grid,
const std::string& userid);
// add item to map of credentials from specific storage
virtual void addToCredentialMap(const std::string& storage,
LLPointer<LLCredential> cred,
bool save_authenticator);
// remove item from map of credentials from specific storage
virtual void removeFromCredentialMap(const std::string& storage,
LLPointer<LLCredential> cred);
// remove item from map of credentials from specific storage
virtual void removeFromCredentialMap(const std::string& storage,
const std::string& grid,
const std::string& userid);
virtual void removeCredentialMap(const std::string& storage,
const std::string& grid);
protected:
void _readProtectedData();
void _writeProtectedData();

View File

@ -236,7 +236,8 @@ LLSLURL LLStartUp::sStartSLURL;
static LLPointer<LLCredential> gUserCredential;
static std::string gDisplayName;
static BOOL gRememberPassword = TRUE;
static bool gRememberPassword = true;
static bool gRememberUser = true;
static U64 gFirstSimHandle = 0;
static LLHost gFirstSim;
@ -701,19 +702,23 @@ bool idle_startup()
else if (gSavedSettings.getBOOL("AutoLogin"))
{
// Log into last account
gRememberPassword = TRUE;
gSavedSettings.setBOOL("RememberPassword", TRUE);
gRememberPassword = true;
gRememberUser = true;
gSavedSettings.setBOOL("RememberPassword", TRUE);
gSavedSettings.setBOOL("RememberUser", TRUE);
show_connect_box = false;
}
else if (gSavedSettings.getLLSD("UserLoginInfo").size() == 3)
{
// Console provided login&password
gRememberPassword = gSavedSettings.getBOOL("RememberPassword");
gRememberUser = gSavedSettings.getBOOL("RememberUser");
show_connect_box = false;
}
else
{
gRememberPassword = gSavedSettings.getBOOL("RememberPassword");
gRememberUser = gSavedSettings.getBOOL("RememberUser");
show_connect_box = TRUE;
}
@ -781,10 +786,7 @@ bool idle_startup()
// Show the login dialog
login_show();
// connect dialog is already shown, so fill in the names
if (gUserCredential.notNull() && !LLPanelLogin::isCredentialSet())
{
LLPanelLogin::setFields( gUserCredential, gRememberPassword);
}
LLPanelLogin::populateFields( gUserCredential, gRememberUser, gRememberPassword);
LLPanelLogin::giveFocus();
// MAINT-3231 Show first run dialog only for Desura viewer
@ -873,7 +875,7 @@ bool idle_startup()
{
// TODO if not use viewer auth
// Load all the name information out of the login view
LLPanelLogin::getFields(gUserCredential, gRememberPassword);
LLPanelLogin::getFields(gUserCredential, gRememberUser, gRememberPassword);
// end TODO
// HACK: Try to make not jump on login
@ -885,14 +887,21 @@ bool idle_startup()
// STATE_LOGIN_SHOW state if we've gone backwards
mLoginStatePastUI = true;
// save the credentials
std::string userid = "unknown";
if(gUserCredential.notNull())
{
userid = gUserCredential->userID();
gSecAPIHandler->saveCredential(gUserCredential, gRememberPassword);
}
gSavedSettings.setBOOL("RememberPassword", gRememberPassword);
// save the credentials
std::string userid = "unknown";
if (gUserCredential.notNull())
{
userid = gUserCredential->userID();
if (gRememberUser)
{
gSecAPIHandler->addToCredentialMap("login_list", gUserCredential, gRememberPassword);
// Legacy viewers use this method to store user credentials, newer viewers
// reuse it to be compatible and to remember last session
gSecAPIHandler->saveCredential(gUserCredential, gRememberPassword);
}
}
gSavedSettings.setBOOL("RememberPassword", gRememberPassword);
gSavedSettings.setBOOL("RememberUser", gRememberUser);
LL_INFOS("AppInit") << "Attempting login as: " << userid << LL_ENDL;
gDebugInfo["LoginName"] = userid;

View File

@ -69,6 +69,7 @@
#include "llfloaterevent.h"
#include "llfloaterflickr.h"
#include "llfloaterfonttest.h"
#include "llfloaterforgetuser.h"
#include "llfloatergesture.h"
#include "llfloatergodtools.h"
#include "llfloatergridstatus.h"
@ -235,6 +236,7 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("experience_search", "floater_experience_search.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterExperiencePicker>);
LLFloaterReg::add("font_test", "floater_font_test.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterFontTest>);
LLFloaterReg::add("forget_username", "floater_forget_user.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterForgetUser>);
LLFloaterReg::add("gestures", "floater_gesture.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterGesture>);
LLFloaterReg::add("god_tools", "floater_god_tools.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterGodTools>);

View File

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater
legacy_header_height="18"
height="258"
layout="topleft"
name="groups"
help_topic="forget_username"
title="REMEMBERED USERNAMES"
width="280">
<scroll_list
height="173"
layout="topleft"
left="12"
name="user_list"
top="24"
width="256">
<scroll_list.columns
name="user"
width="248" />
</scroll_list>
<button
height="20"
label="Forget"
label_selected="Forget"
layout="topleft"
left_delta="90"
name="forget"
top_pad="8"
width="80" />
<check_box
height="20"
label="Also delete local data for this username"
layout="topleft"
left="15"
name="delete_data"
top_pad="5"
width="260"
initial_value="1"
tooltip="Deletes local files: chat history, last session screenshot, browser cookies, teleport history, toolbar settings, e t c"/>
</floater>

View File

@ -57,19 +57,15 @@
combo_editor.prevalidate_callback="ascii"
tool_tip="The username you chose when you registered, like bobsmith12 or Steller Sunshine"
name="username_combo"
width="232">
width="206">
<combo_box.combo_editor
text_pad_left="8"
bg_image_always_focused="true"/>
<combo_box.combo_button
visible="false" />
<combo_box.drop_down_button
visible="false" />
</combo_box>
<line_editor
follows="left|top"
height="32"
left_pad="-11"
left_pad="15"
max_length_chars="16"
text_pad_left="8"
name="password_edit"
@ -119,36 +115,49 @@
width="120"
height="32"
left_pad="15"
bottom_delta="0" />
bottom_delta="0" />
<text
follows="left|top"
font="SansSerifLarge"
font.style="BOLD"
text_color="EmphasisColor"
height="34"
name="sign_up_text"
left_pad="10"
width="200"
valign="center">
Sign up
</text>
<check_box
follows="left|top"
font="SansSerifMedium"
left="185"
bottom_delta="21"
height="24"
label="Remember me"
check_button.bottom="3"
name="remember_name"
tooltip="Already recorded user can be forgotten from preferences."
width="145" />
<check_box
control_name="RememberPassword"
follows="left|top"
font="SansSerifMedium"
left="185"
bottom_delta="21"
height="24"
label="Remember me"
text_color="EmphasisColor"
height="16"
left="408"
bottom_delta="0"
label="Remember password"
check_button.bottom="3"
name="remember_check"
width="145" />
<text
follows="left|top"
font="SansSerifMedium"
text_color="EmphasisColor"
height="16"
name="forgot_password_text"
left="408"
bottom_delta="0"
width="200">
Forgotten password
</text>
<combo_box
allow_text_entry="false"
font="SansSerifTiny"
follows="left|top"
height="26"
left="588"
bottom_delta="10"
bottom_delta="8"
max_chars="128"
label="Select grid"
layout="topleft"
@ -159,12 +168,13 @@
font="SansSerifMedium"
text_color="EmphasisColor"
height="16"
name="sign_up_text"
name="forgot_password_text"
left="778"
bottom_delta="-10"
width="200">
Sign up
</text>
bottom_delta="-8"
width="120"
halign="center">
Password help
</text>
</layout_panel>
<layout_panel
height="172"

View File

@ -248,14 +248,27 @@
top_pad="5"
width="237"/>
<button
height="20"
label="Default Creation Permissions"
follows="top|left"
layout="topleft"
name="default_creation_permissions"
label="Remembered Usernames"
name="remembered_usernames"
height="20"
left="30"
top_pad = "20"
width="250">
<button.commit_callback
function="Pref.PermsDefault" />
top_pad="16"
width="200">
<button.commit_callback
function="Pref.RememberedUsernames" />
</button>
<button
follows="top|left"
layout="topleft"
label="Default Creation Permissions"
name="default_creation_permissions"
height="20"
left="30"
top_pad="16"
width="200">
<button.commit_callback
function="Pref.PermsDefault" />
</button>
</panel>

View File

@ -60,12 +60,21 @@ LLPointer<LLCertificate> LLSecAPIBasicHandler::getCertificate(X509* openssl_cert
LLPointer<LLCertificateChain> LLSecAPIBasicHandler::getCertificateChain(const X509_STORE_CTX* chain) { return NULL; }
LLPointer<LLCertificateStore> LLSecAPIBasicHandler::getCertificateStore(const std::string& store_id) { return NULL; }
void LLSecAPIBasicHandler::setProtectedData(const std::string& data_type, const std::string& data_id, const LLSD& data) {}
void LLSecAPIBasicHandler::addToProtectedMap(const std::string& data_type, const std::string& data_id, const std::string& map_elem, const LLSD& data) {}
void LLSecAPIBasicHandler::removeFromProtectedMap(const std::string& data_type, const std::string& data_id, const std::string& map_elem) {}
LLSD LLSecAPIBasicHandler::getProtectedData(const std::string& data_type, const std::string& data_id) { return LLSD(); }
void LLSecAPIBasicHandler::deleteProtectedData(const std::string& data_type, const std::string& data_id) {}
LLPointer<LLCredential> LLSecAPIBasicHandler::createCredential(const std::string& grid, const LLSD& identifier, const LLSD& authenticator) { return NULL; }
LLPointer<LLCredential> LLSecAPIBasicHandler::loadCredential(const std::string& grid) { return NULL; }
void LLSecAPIBasicHandler::saveCredential(LLPointer<LLCredential> cred, bool save_authenticator) {}
void LLSecAPIBasicHandler::deleteCredential(LLPointer<LLCredential> cred) {}
bool LLSecAPIBasicHandler::hasCredentialMap(const std::string& storage, const std::string& grid) { return false; }
void LLSecAPIBasicHandler::loadCredentialMap(const std::string& storage, const std::string& grid, credential_map_t& credential_map) {}
LLPointer<LLCredential> LLSecAPIBasicHandler::loadFromCredentialMap(const std::string& storage, const std::string& grid, const std::string& userkey) { return NULL; }
void LLSecAPIBasicHandler::addToCredentialMap(const std::string& storage, LLPointer<LLCredential> cred, bool save_authenticator) {}
void LLSecAPIBasicHandler::removeFromCredentialMap(const std::string& storage, LLPointer<LLCredential> cred) {}
void LLSecAPIBasicHandler::removeFromCredentialMap(const std::string& storage, const std::string& grid, const std::string& userkey) {}
void LLSecAPIBasicHandler::removeCredentialMap(const std::string& storage, const std::string& grid) {}
// -------------------------------------------------------------------------------------------
// TUT