PageRenderTime 27ms CodeModel.GetById 1ms app.highlight 22ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/newview/llpanelmediasettingssecurity.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 356 lines | 209 code | 50 blank | 97 comment | 23 complexity | dfb9237f62c2f0147e9062c8c7c196f5 MD5 | raw file
  1/**
  2 * @file llpanelmediasettingssecurity.cpp
  3 * @brief LLPanelMediaSettingsSecurity class implementation
  4 *
  5 * $LicenseInfo:firstyear=2009&license=viewerlgpl$
  6 * Second Life Viewer Source Code
  7 * Copyright (C) 2010, Linden Research, Inc.
  8 * 
  9 * This library is free software; you can redistribute it and/or
 10 * modify it under the terms of the GNU Lesser General Public
 11 * License as published by the Free Software Foundation;
 12 * version 2.1 of the License only.
 13 * 
 14 * This library is distributed in the hope that it will be useful,
 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 17 * Lesser General Public License for more details.
 18 * 
 19 * You should have received a copy of the GNU Lesser General Public
 20 * License along with this library; if not, write to the Free Software
 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 22 * 
 23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 24 * $/LicenseInfo$
 25 */
 26
 27#include "llviewerprecompiledheaders.h"
 28
 29#include "llpanelmediasettingssecurity.h"
 30
 31#include "llfloaterreg.h"
 32#include "llpanelcontents.h"
 33#include "llcheckboxctrl.h"
 34#include "llnotificationsutil.h"
 35#include "llscrolllistctrl.h"
 36#include "llscrolllistitem.h"
 37#include "lluictrlfactory.h"
 38#include "llwindow.h"
 39#include "llviewerwindow.h"
 40#include "llsdutil.h"
 41#include "llselectmgr.h"
 42#include "llmediaentry.h"
 43#include "lltextbox.h"
 44#include "llfloaterwhitelistentry.h"
 45#include "llfloatermediasettings.h"
 46
 47////////////////////////////////////////////////////////////////////////////////
 48//
 49LLPanelMediaSettingsSecurity::LLPanelMediaSettingsSecurity() :
 50	mParent( NULL )
 51{
 52	mCommitCallbackRegistrar.add("Media.whitelistAdd",		boost::bind(&LLPanelMediaSettingsSecurity::onBtnAdd, this));
 53	mCommitCallbackRegistrar.add("Media.whitelistDelete",	boost::bind(&LLPanelMediaSettingsSecurity::onBtnDel, this));	
 54
 55	// build dialog from XML
 56	buildFromFile( "panel_media_settings_security.xml");
 57}
 58
 59////////////////////////////////////////////////////////////////////////////////
 60//
 61BOOL LLPanelMediaSettingsSecurity::postBuild()
 62{
 63	mEnableWhiteList = getChild< LLCheckBoxCtrl >( LLMediaEntry::WHITELIST_ENABLE_KEY );
 64	mWhiteListList = getChild< LLScrollListCtrl >( LLMediaEntry::WHITELIST_KEY );
 65	mHomeUrlFailsWhiteListText = getChild<LLTextBox>( "home_url_fails_whitelist" );
 66	
 67	setDefaultBtn("whitelist_add");
 68
 69	return true;
 70}
 71
 72////////////////////////////////////////////////////////////////////////////////
 73// virtual
 74LLPanelMediaSettingsSecurity::~LLPanelMediaSettingsSecurity()
 75{
 76}
 77
 78////////////////////////////////////////////////////////////////////////////////
 79// 
 80void LLPanelMediaSettingsSecurity::draw()
 81{
 82	// housekeeping
 83	LLPanel::draw();
 84}
 85
 86////////////////////////////////////////////////////////////////////////////////
 87// static 
 88void LLPanelMediaSettingsSecurity::initValues( void* userdata, const LLSD& media_settings , bool editable)
 89{
 90	LLPanelMediaSettingsSecurity *self =(LLPanelMediaSettingsSecurity *)userdata;
 91	std::string base_key( "" );
 92	std::string tentative_key( "" );
 93
 94	struct 
 95	{
 96		std::string key_name;
 97		LLUICtrl* ctrl_ptr;
 98		std::string ctrl_type;
 99
100	} data_set [] = 
101	{
102		{ LLMediaEntry::WHITELIST_ENABLE_KEY,	self->mEnableWhiteList,		"LLCheckBoxCtrl" },
103		{ LLMediaEntry::WHITELIST_KEY,			self->mWhiteListList,		"LLScrollListCtrl" },
104		{ "", NULL , "" }
105	};
106
107	for( int i = 0; data_set[ i ].key_name.length() > 0; ++i )
108	{
109		base_key = std::string( data_set[ i ].key_name );
110        tentative_key = base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX );
111
112		bool enabled_overridden = false;
113		
114		// TODO: CP - I bet there is a better way to do this using Boost
115		if ( media_settings[ base_key ].isDefined() )
116		{
117			if ( data_set[ i ].ctrl_type == "LLCheckBoxCtrl" )
118			{
119				static_cast< LLCheckBoxCtrl* >( data_set[ i ].ctrl_ptr )->
120					setValue( media_settings[ base_key ].asBoolean() );
121			}
122			else
123			if ( data_set[ i ].ctrl_type == "LLScrollListCtrl" )
124			{
125				// get control 
126				LLScrollListCtrl* list = static_cast< LLScrollListCtrl* >( data_set[ i ].ctrl_ptr );
127				list->deleteAllItems();
128				
129				// points to list of white list URLs
130				LLSD url_list = media_settings[ base_key ];
131				
132				// better be the whitelist
133				llassert(data_set[ i ].ctrl_ptr == self->mWhiteListList);
134				
135				// If tentative, don't add entries
136				if (media_settings[ tentative_key ].asBoolean())
137				{
138					self->mWhiteListList->setEnabled(false);
139					enabled_overridden = true;
140				}
141				else {
142					// iterate over them and add to scroll list
143					LLSD::array_iterator iter = url_list.beginArray();
144					while( iter != url_list.endArray() )
145					{
146						std::string entry = *iter;
147						self->addWhiteListEntry( entry );
148						++iter;
149					}
150				}
151			};
152			if ( ! enabled_overridden) data_set[ i ].ctrl_ptr->setEnabled(editable);
153			data_set[ i ].ctrl_ptr->setTentative( media_settings[ tentative_key ].asBoolean() );
154		};
155	};
156
157	// initial update - hides/shows status messages etc.
158	self->updateWhitelistEnableStatus();
159}
160
161////////////////////////////////////////////////////////////////////////////////
162// static 
163void LLPanelMediaSettingsSecurity::clearValues( void* userdata , bool editable)
164{
165	LLPanelMediaSettingsSecurity *self =(LLPanelMediaSettingsSecurity *)userdata;
166	self->mEnableWhiteList->clear();
167	self->mWhiteListList->deleteAllItems();
168	self->mEnableWhiteList->setEnabled(editable);
169	self->mWhiteListList->setEnabled(editable);
170}
171
172////////////////////////////////////////////////////////////////////////////////
173// 
174void LLPanelMediaSettingsSecurity::preApply()
175{
176	// no-op
177}
178
179////////////////////////////////////////////////////////////////////////////////
180//
181void LLPanelMediaSettingsSecurity::getValues( LLSD &fill_me_in, bool include_tentative )
182{
183    if (include_tentative || !mEnableWhiteList->getTentative()) 
184		fill_me_in[LLMediaEntry::WHITELIST_ENABLE_KEY] = (LLSD::Boolean)mEnableWhiteList->getValue();
185	
186	if (include_tentative || !mWhiteListList->getTentative())
187	{
188		// iterate over white list and extract items
189		std::vector< LLScrollListItem* > whitelist_items = mWhiteListList->getAllData();
190		std::vector< LLScrollListItem* >::iterator iter = whitelist_items.begin();
191		
192		// *NOTE: need actually set the key to be an emptyArray(), or the merge
193		// we do with this LLSD will think there's nothing to change.
194		fill_me_in[LLMediaEntry::WHITELIST_KEY] = LLSD::emptyArray();
195		while( iter != whitelist_items.end() )
196		{
197			LLScrollListCell* cell = (*iter)->getColumn( ENTRY_COLUMN );
198			std::string whitelist_url = cell->getValue().asString();
199			
200			fill_me_in[ LLMediaEntry::WHITELIST_KEY ].append( whitelist_url );
201			++iter;
202		};
203	}
204}
205
206////////////////////////////////////////////////////////////////////////////////
207// 
208void LLPanelMediaSettingsSecurity::postApply()
209{
210	// no-op
211}
212
213///////////////////////////////////////////////////////////////////////////////
214// Try to make a valid URL if a fragment (
215// white list list box widget and build a list to test against. Can also
216const std::string LLPanelMediaSettingsSecurity::makeValidUrl( const std::string& src_url )
217{
218	// use LLURI to determine if we have a valid scheme
219	LLURI candidate_url( src_url );
220	if ( candidate_url.scheme().empty() )
221	{
222		// build a URL comprised of default scheme and the original fragment 
223		const std::string default_scheme( "http://" );
224		return default_scheme + src_url;
225	};
226
227	// we *could* test the "default scheme" + "original fragment" URL again
228	// using LLURI to see if it's valid but I think the outcome is the same
229	// in either case - our only option is to return the original URL
230
231	// we *think* the original url passed in was valid
232	return src_url;
233}
234
235///////////////////////////////////////////////////////////////////////////////
236// wrapper for testing a URL against the whitelist. We grab entries from
237// white list list box widget and build a list to test against. 
238bool LLPanelMediaSettingsSecurity::urlPassesWhiteList( const std::string& test_url )
239{
240	// If the whitlelist list is tentative, it means we have multiple settings.
241	// In that case, we have no choice but to return true
242	if ( mWhiteListList->getTentative() ) return true;
243	
244	// the checkUrlAgainstWhitelist(..) function works on a vector
245	// of strings for the white list entries - in this panel, the white list
246	// is stored in the widgets themselves so we need to build something compatible.
247	std::vector< std::string > whitelist_strings;
248	whitelist_strings.clear();	// may not be required - I forget what the spec says.
249
250	// step through whitelist widget entries and grab them as strings
251    std::vector< LLScrollListItem* > whitelist_items = mWhiteListList->getAllData();
252    std::vector< LLScrollListItem* >::iterator iter = whitelist_items.begin(); 
253	while( iter != whitelist_items.end()  )
254    {
255		LLScrollListCell* cell = (*iter)->getColumn( ENTRY_COLUMN );
256		std::string whitelist_url = cell->getValue().asString();
257
258		whitelist_strings.push_back( whitelist_url );
259
260		++iter;
261    };
262
263	// possible the URL is just a fragment so we validize it
264	const std::string valid_url = makeValidUrl( test_url );
265
266	// indicate if the URL passes whitelist
267	return LLMediaEntry::checkUrlAgainstWhitelist( valid_url, whitelist_strings );
268}
269
270///////////////////////////////////////////////////////////////////////////////
271//
272void LLPanelMediaSettingsSecurity::updateWhitelistEnableStatus()
273{
274	// get the value for home URL and make it a valid URL
275	const std::string valid_url = makeValidUrl( mParent->getHomeUrl() );
276
277	// now check to see if the home url passes the whitelist in its entirity 
278	if ( urlPassesWhiteList( valid_url ) )
279	{
280		mEnableWhiteList->setEnabled( true );
281		mHomeUrlFailsWhiteListText->setVisible( false );
282	}
283	else
284	{
285		mEnableWhiteList->set( false );
286		mEnableWhiteList->setEnabled( false );
287		mHomeUrlFailsWhiteListText->setVisible( true );
288	};
289}
290
291///////////////////////////////////////////////////////////////////////////////
292// Add an entry to the whitelist scrollbox and indicate if the current
293// home URL passes this entry or not using an icon
294void LLPanelMediaSettingsSecurity::addWhiteListEntry( const std::string& entry )
295{
296	// grab the home url
297	std::string home_url( "" );
298	if ( mParent )
299		home_url = mParent->getHomeUrl();
300
301	// try to make a valid URL based on what the user entered - missing scheme for example
302	const std::string valid_url = makeValidUrl( home_url );
303
304	// check the home url against this single whitelist entry
305	std::vector< std::string > whitelist_entries;
306	whitelist_entries.push_back( entry );
307	bool home_url_passes_entry = LLMediaEntry::checkUrlAgainstWhitelist( valid_url, whitelist_entries );
308
309	// build an icon cell based on whether or not the home url pases it or not
310	LLSD row;
311	if ( home_url_passes_entry || home_url.empty() )
312	{
313		row[ "columns" ][ ICON_COLUMN ][ "type" ] = "icon";
314		row[ "columns" ][ ICON_COLUMN ][ "value" ] = "";
315		row[ "columns" ][ ICON_COLUMN ][ "width" ] = 20;
316	}
317	else
318	{
319		row[ "columns" ][ ICON_COLUMN ][ "type" ] = "icon";
320		row[ "columns" ][ ICON_COLUMN ][ "value" ] = "Parcel_Exp_Color";
321		row[ "columns" ][ ICON_COLUMN ][ "width" ] = 20;
322	};
323
324	// always add in the entry itself
325	row[ "columns" ][ ENTRY_COLUMN ][ "type" ] = "text";
326	row[ "columns" ][ ENTRY_COLUMN ][ "value" ] = entry;
327	
328	// add to the white list scroll box
329	mWhiteListList->addElement( row );
330};
331
332///////////////////////////////////////////////////////////////////////////////
333// static
334void LLPanelMediaSettingsSecurity::onBtnAdd( void* userdata )
335{
336	LLFloaterReg::showInstance("whitelist_entry");
337}
338
339///////////////////////////////////////////////////////////////////////////////
340// static
341void LLPanelMediaSettingsSecurity::onBtnDel( void* userdata )
342{
343	LLPanelMediaSettingsSecurity *self =(LLPanelMediaSettingsSecurity *)userdata;
344
345	self->mWhiteListList->deleteSelectedItems();
346
347	// contents of whitelist changed so recheck it against home url
348	self->updateWhitelistEnableStatus();
349}
350
351////////////////////////////////////////////////////////////////////////////////
352//
353void LLPanelMediaSettingsSecurity::setParent( LLFloaterMediaSettings* parent )
354{
355	mParent = parent;
356};