Added support into client for openid
This commit is contained in:
Drake Arconis
2012-08-03 11:32:36 -04:00
parent af89351432
commit c90c8e0f4b
10 changed files with 308 additions and 14 deletions

View File

@@ -7154,6 +7154,17 @@
<key>Value</key>
<string>help/index.html</string>
</map>
<key>WebProfileURL</key>
<map>
<key>Comment</key>
<string>URL for Web Profiles</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
<string>String</string>
<key>Value</key>
<string>https://my.secondlife.com/[AGENT_NAME]</string>
</map>
<key>HighResSnapshot</key>
<map>
<key>Comment</key>

View File

@@ -42,6 +42,7 @@
#include "llcommandhandler.h"
#include "llpanelavatar.h"
#include "lluictrlfactory.h"
#include "llweb.h"
// linden library includes
#include "llinventory.h"
@@ -293,3 +294,13 @@ LLPreview::EAssetStatus LLFloaterAvatarInfo::getAssetStatus()
}
return mAssetStatus;
}
std::string getProfileURL(const std::string& agent_name)
{
std::string url = gSavedSettings.getString("WebProfileURL");
LLSD subs;
subs["AGENT_NAME"] = agent_name;
url = LLWeb::expandURLSubstitutions(url,subs);
LLStringUtil::toLower(url);
return url;
}

View File

@@ -101,5 +101,6 @@ private:
EOnlineStatus mSuggestedOnlineStatus;
};
std::string getProfileURL(const std::string& agent_name);
#endif

View File

@@ -4306,7 +4306,6 @@ bool process_login_success_response(std::string& password)
#endif
}
// Override grid info with anything sent in the login response
std::string tmp = response["gridname"].asString();
if (!tmp.empty()) gHippoGridManager->getConnectedGrid()->setGridName(tmp);
@@ -4351,6 +4350,14 @@ bool process_login_success_response(std::string& password)
gHippoGridManager->saveFile();
gHippoLimits->setLimits();
// Start the process of fetching the OpenID session cookie for this user login
std::string openid_url = response["openid_url"];
if(!openid_url.empty())
{
std::string openid_token = response["openid_token"];
LLViewerMedia::openIDSetup(openid_url, openid_token);
}
gIMMgr->loadIgnoreGroup();
bool success = false;

View File

@@ -286,5 +286,11 @@ const char * LLURL::getFullPath()
return(sReturnString);
}
const char * LLURL::getAuthority()
{
strncpy(LLURL::sReturnString,mAuthority, LL_MAX_PATH -1); /* Flawfinder: ignore */
LLURL::sReturnString[LL_MAX_PATH -1] = '\0';
return(sReturnString);
}
char LLURL::sReturnString[LL_MAX_PATH] = "";

View File

@@ -79,6 +79,7 @@ public:
virtual const char *getFQURL() const;
virtual const char *getFullPath();
virtual const char *getAuthority();
virtual const char *updateRelativePath(const LLURL &url);

View File

@@ -55,6 +55,7 @@
#include "llvieweraudio.h"
#include "llweb.h"
#include "llfloateravatarinfo.h" // for getProfileURL() function
//#include "viewerversion.h"
// Merov: Temporary definitions while porting the new viewer media code to Snowglobe
@@ -83,11 +84,6 @@ public:
completeAny(status, mime_type);
}
virtual void error( U32 status, const std::string& reason )
{
// completeAny(status, "none/none");
}
void completeAny(U32 status, const std::string& mime_type)
{
if(!mInitialized && ! mime_type.empty())
@@ -104,9 +100,81 @@ public:
viewer_media_t mMediaImpl;
bool mInitialized;
};
class LLViewerMediaOpenIDResponder : public LLHTTPClient::Responder
{
LOG_CLASS(LLViewerMediaOpenIDResponder);
public:
LLViewerMediaOpenIDResponder( )
{
}
~LLViewerMediaOpenIDResponder()
{
}
/* virtual */ void completedHeader(U32 status, const std::string& reason, const LLSD& content)
{
LL_DEBUGS("MediaAuth") << "status = " << status << ", reason = " << reason << LL_ENDL;
LL_DEBUGS("MediaAuth") << content << LL_ENDL;
std::string cookie = content["set-cookie"].asString();
LLViewerMedia::openIDCookieResponse(cookie);
}
/* virtual */ void completedRaw(
U32 status,
const std::string& reason,
const LLChannelDescriptors& channels,
const LLIOPipe::buffer_ptr_t& buffer)
{
// This is just here to disable the default behavior (attempting to parse the response as llsd).
// We don't care about the content of the response, only the set-cookie header.
}
};
class LLViewerMediaWebProfileResponder : public LLHTTPClient::Responder
{
LOG_CLASS(LLViewerMediaWebProfileResponder);
public:
LLViewerMediaWebProfileResponder(std::string host)
{
mHost = host;
}
~LLViewerMediaWebProfileResponder()
{
}
/* virtual */ void completedHeader(U32 status, const std::string& reason, const LLSD& content)
{
LL_WARNS("MediaAuth") << "status = " << status << ", reason = " << reason << LL_ENDL;
LL_WARNS("MediaAuth") << content << LL_ENDL;
std::string cookie = content["set-cookie"].asString();
LLViewerMedia::getCookieStore()->setCookiesFromHost(cookie, mHost);
}
void completedRaw(
U32 status,
const std::string& reason,
const LLChannelDescriptors& channels,
const LLIOPipe::buffer_ptr_t& buffer)
{
// This is just here to disable the default behavior (attempting to parse the response as llsd).
// We don't care about the content of the response, only the set-cookie header.
}
std::string mHost;
};
LLPluginCookieStore *LLViewerMedia::sCookieStore = NULL;
LLURL LLViewerMedia::sOpenIDURL;
std::string LLViewerMedia::sOpenIDCookie;
typedef std::list<LLViewerMediaImpl*> impl_list;
static impl_list sViewerMediaImplList;
LLPluginCookieStore *LLViewerMedia::sCookieStore = NULL;
static std::string sUpdatedCookies;
static const char *PLUGIN_COOKIE_FILE_NAME = "plugin_cookies.txt";
@@ -370,6 +438,9 @@ void LLViewerMedia::clearAllCookies()
LLFile::remove(target);
}
}
// If we have an OpenID cookie, re-add it to the cookie store.
setOpenIDCookie();
}
/////////////////////////////////////////////////////////////////////////////////////////
@@ -453,6 +524,9 @@ void LLViewerMedia::loadCookieFile()
plugin->clear_cookies();
}
}
// If we have an OpenID cookie, re-add it to the cookie store.
setOpenIDCookie();
}
@@ -523,6 +597,112 @@ void LLViewerMedia::removeCookie(const std::string &name, const std::string &dom
addCookie(name, "", domain, LLDate(LLDate::now().secondsSinceEpoch() - 1.0), path);
}
LLSD LLViewerMedia::getHeaders()
{
LLSD headers = LLSD::emptyMap();
headers["Accept"] = "*/*";
headers["Content-Type"] = "application/xml";
headers["Cookie"] = sOpenIDCookie;
headers["User-Agent"] = getCurrentUserAgent();
return headers;
}
/////////////////////////////////////////////////////////////////////////////////////////
// static
void LLViewerMedia::setOpenIDCookie()
{
if(!sOpenIDCookie.empty())
{
// The LLURL can give me the 'authority', which is of the form: [username[:password]@]hostname[:port]
// We want just the hostname for the cookie code, but LLURL doesn't seem to have a way to extract that.
// We therefore do it here.
std::string authority = sOpenIDURL.mAuthority;
std::string::size_type host_start = authority.find('@');
if(host_start == std::string::npos)
{
// no username/password
host_start = 0;
}
else
{
// Hostname starts after the @.
// (If the hostname part is empty, this may put host_start at the end of the string. In that case, it will end up passing through an empty hostname, which is correct.)
++host_start;
}
std::string::size_type host_end = authority.rfind(':');
if((host_end == std::string::npos) || (host_end < host_start))
{
// no port
host_end = authority.size();
}
getCookieStore()->setCookiesFromHost(sOpenIDCookie, authority.substr(host_start, host_end - host_start));
// Do a web profile get so we can store the cookie
LLSD headers = LLSD::emptyMap();
headers["Accept"] = "*/*";
headers["Cookie"] = sOpenIDCookie;
headers["User-Agent"] = getCurrentUserAgent();
std::string profile_url = getProfileURL("");
LLURL raw_profile_url( profile_url.c_str() );
LL_DEBUGS("MediaAuth") << "Requesting " << profile_url << llendl;
LL_DEBUGS("MediaAuth") << "sOpenIDCookie = [" << sOpenIDCookie << "]" << llendl;
LLHTTPClient::get(profile_url,
new LLViewerMediaWebProfileResponder(raw_profile_url.getAuthority()),
headers);
}
}
/////////////////////////////////////////////////////////////////////////////////////////
// static
void LLViewerMedia::openIDSetup(const std::string &openid_url, const std::string &openid_token)
{
LL_DEBUGS("MediaAuth") << "url = \"" << openid_url << "\", token = \"" << openid_token << "\"" << LL_ENDL;
// post the token to the url
// the responder will need to extract the cookie(s).
// Save the OpenID URL for later -- we may need the host when adding the cookie.
sOpenIDURL.init(openid_url.c_str());
// We shouldn't ever do this twice, but just in case this code gets repurposed later, clear existing cookies.
sOpenIDCookie.clear();
LLSD headers = LLSD::emptyMap();
// Keep LLHTTPClient from adding an "Accept: application/llsd+xml" header
headers["Accept"] = "*/*";
// and use the expected content-type for a post, instead of the LLHTTPClient::postRaw() default of "application/octet-stream"
headers["Content-Type"] = "application/x-www-form-urlencoded";
// postRaw() takes ownership of the buffer and releases it later, so we need to allocate a new buffer here.
size_t size = openid_token.size();
U8 *data = new U8[size];
memcpy(data, openid_token.data(), size);
LLHTTPClient::postRaw(
openid_url,
data,
size,
new LLViewerMediaOpenIDResponder(),
headers);
}
/////////////////////////////////////////////////////////////////////////////////////////
// static
void LLViewerMedia::openIDCookieResponse(const std::string &cookie)
{
LL_DEBUGS("MediaAuth") << "Cookie received: \"" << cookie << "\"" << LL_ENDL;
sOpenIDCookie += cookie;
setOpenIDCookie();
}
//////////////////////////////////////////////////////////////////////////////////////////
// static
void LLViewerMedia::cleanupClass()

View File

@@ -92,8 +92,17 @@ class LLViewerMedia
static void addSessionCookie(const std::string &name, const std::string &value, const std::string &domain, const std::string &path = std::string("/"), bool secure = false );
static void removeCookie(const std::string &name, const std::string &domain, const std::string &path = std::string("/") );
static void openIDSetup(const std::string &openid_url, const std::string &openid_token);
static void openIDCookieResponse(const std::string &cookie);
static LLSD getHeaders();
private:
static void setOpenIDCookie();
static LLPluginCookieStore *sCookieStore;
static LLURL sOpenIDURL;
static std::string sOpenIDCookie;
};
// Implementation functions not exported into header file
@@ -104,7 +113,6 @@ class LLViewerMediaImpl
public:
friend class LLViewerMedia;
friend class LLMimeDiscoveryResponder;
LLViewerMediaImpl(const std::string& media_url,
const LLUUID& texture_id,
@@ -123,9 +131,6 @@ public:
LLPluginClassMedia* getMediaPlugin() const { return (LLPluginClassMedia*)mPluginBase; }
void setSize(int width, int height);
// Inherited from LLViewerPluginManager.
/*virtual*/ void update();
void play();
void stop();
void pause();
@@ -155,6 +160,7 @@ public:
void scaleMouse(S32 *mouse_x, S32 *mouse_y);
void updateMovieImage(const LLUUID& image_id, BOOL active);
void update();
void updateImagesMediaStreams();
LLUUID getMediaTextureID();

View File

@@ -35,11 +35,20 @@
#include "llweb.h"
#include "llviewerwindow.h"
#include "llwindow.h"
// Library includes
#include "llwindow.h" // spawnWebBrowser()
#include "llviewercontrol.h"
#include "llagent.h"
#include "llappviewer.h"
#include "llfloatermediabrowser.h"
#include "llparcel.h"
#include "llviewercontrol.h"
#include "llviewernetwork.h"
#include "llviewerparcelmgr.h"
#include "llviewerregion.h"
#include "llviewerwindow.h"
#include "sgversion.h"
// static
void LLWeb::initClass()
@@ -125,6 +134,64 @@ std::string LLWeb::escapeURL(const std::string& url)
return escaped_url;
}
//static
std::string LLWeb::expandURLSubstitutions(const std::string &url,
const LLSD &default_subs)
{
gCurrentVersion = llformat("%s %d.%d.%d.%d",
gVersionChannel,
gVersionMajor,
gVersionMinor,
gVersionPatch,
gVersionBuild );
LLSD substitution = default_subs;
substitution["VERSION"] = gCurrentVersion;
substitution["VERSION_MAJOR"] = gVersionMajor;
substitution["VERSION_MINOR"] = gVersionMinor;
substitution["VERSION_PATCH"] = gVersionPatch;
substitution["VERSION_BUILD"] = gVersionBuild;
substitution["CHANNEL"] = gVersionChannel;
substitution["GRID"] = LLViewerLogin::getInstance()->getGridLabel();
substitution["OS"] = LLAppViewer::instance()->getOSInfo().getOSStringSimple();
substitution["SESSION_ID"] = gAgent.getSessionID();
substitution["FIRST_LOGIN"] = gAgent.isFirstLogin();
// work out the current language
std::string lang = LLUI::getLanguage();
if (lang == "en-us")
{
// *HACK: the correct fix is to change English.lproj/language.txt,
// but we're late in the release cycle and this is a less risky fix
lang = "en";
}
substitution["LANGUAGE"] = lang;
// find the region ID
LLUUID region_id;
LLViewerRegion *region = gAgent.getRegion();
if (region)
{
region_id = region->getRegionID();
}
substitution["REGION_ID"] = region_id;
// find the parcel local ID
S32 parcel_id = 0;
LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
if (parcel)
{
parcel_id = parcel->getLocalID();
}
substitution["PARCEL_ID"] = llformat("%d", parcel_id);
// expand all of the substitution strings and escape the url
std::string expanded_url = url;
LLStringUtil::format(expanded_url, substitution);
return LLWeb::escapeURL(expanded_url);
}
// virtual
void LLWeb::URLLoader::load(const std::string& url)
{

View File

@@ -57,6 +57,10 @@ public:
// Returns escaped (eg, " " to "%20") url
static std::string escapeURL(const std::string& url);
/// Expands various strings like [LANG], [VERSION], etc. in a URL
static std::string expandURLSubstitutions(const std::string &url,
const LLSD &default_subs);
class URLLoader : public LLAlertDialog::URLLoader
{
virtual void load(const std::string& url);