1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_cui.hxx"
26 
27 // include ---------------------------------------------------------------
28 #include <dialmgr.hxx>
29 #include <cuires.hrc>
30 #include <com/sun/star/task/UrlRecord.hpp>
31 #include <com/sun/star/task/XPasswordContainer.hpp>
32 #include <com/sun/star/task/XMasterPasswordHandling.hpp>
33 #include "com/sun/star/task/XUrlContainer.hpp"
34 #include <comphelper/processfactory.hxx>
35 #include <comphelper/docpasswordrequest.hxx>
36 #include "webconninfo.hxx"
37 #include "webconninfo.hrc"
38 
39 using namespace ::com::sun::star;
40 
41 //........................................................................
42 namespace svx
43 {
44 //........................................................................
45 
46 // class PasswordTable ---------------------------------------------------
47 
PasswordTable(Window * pParent,const ResId & rResId)48 PasswordTable::PasswordTable( Window* pParent, const ResId& rResId ) :
49     SvxSimpleTable( pParent, rResId )
50 {
51     SetStyle( GetStyle() | WB_NOINITIALSELECTION );
52 }
53 
InsertHeaderItem(sal_uInt16 nColumn,const String & rText,HeaderBarItemBits nBits)54 void PasswordTable::InsertHeaderItem( sal_uInt16 nColumn, const String& rText, HeaderBarItemBits nBits )
55 {
56     GetTheHeaderBar()->InsertItem( nColumn, rText, 0, nBits );
57 }
58 
ResetTabs()59 void PasswordTable::ResetTabs()
60 {
61     SetTabs();
62 }
63 
Resort(bool bForced)64 void PasswordTable::Resort( bool bForced )
65 {
66     sal_uInt16 nColumn = GetSelectedCol();
67     if ( 0 == nColumn || bForced ) // only the first column is sorted
68     {
69         HeaderBarItemBits nBits = GetTheHeaderBar()->GetItemBits(1);
70         sal_Bool bUp = ( ( nBits & HIB_UPARROW ) == HIB_UPARROW );
71         SvSortMode eMode = SortAscending;
72 
73         if ( bUp )
74         {
75             nBits &= ~HIB_UPARROW;
76             nBits |= HIB_DOWNARROW;
77             eMode = SortDescending;
78         }
79         else
80         {
81             nBits &= ~HIB_DOWNARROW;
82             nBits |= HIB_UPARROW;
83         }
84         GetTheHeaderBar()->SetItemBits( 1, nBits );
85         SvTreeList* pListModel = GetModel();
86         pListModel->SetSortMode( eMode );
87         pListModel->Resort();
88     }
89 }
90 
91 // class WebConnectionInfoDialog -----------------------------------------
92 
93 // -----------------------------------------------------------------------
WebConnectionInfoDialog(Window * pParent)94 WebConnectionInfoDialog::WebConnectionInfoDialog( Window* pParent ) :
95      ModalDialog( pParent, CUI_RES( RID_SVXDLG_WEBCONNECTION_INFO ) )
96     ,m_aNeverShownFI    ( this, CUI_RES( FI_NEVERSHOWN ) )
97     ,m_aPasswordsLB     ( this, CUI_RES( LB_PASSWORDS ) )
98     ,m_aRemoveBtn       ( this, CUI_RES( PB_REMOVE ) )
99     ,m_aRemoveAllBtn    ( this, CUI_RES( PB_REMOVEALL ) )
100     ,m_aChangeBtn       ( this, CUI_RES( PB_CHANGE ) )
101     ,m_aButtonsFL       ( this, CUI_RES( FL_BUTTONS ) )
102     ,m_aCloseBtn        ( this, CUI_RES( PB_CLOSE ) )
103     ,m_aHelpBtn         ( this, CUI_RES( PB_HELP ) )
104     ,m_nPos             ( -1 )
105 {
106     static long aStaticTabs[]= { 3, 0, 150, 250 };
107     m_aPasswordsLB.SetTabs( aStaticTabs );
108     m_aPasswordsLB.InsertHeaderItem( 1, CUI_RESSTR( STR_WEBSITE ),
109         HIB_LEFT | HIB_VCENTER | HIB_FIXEDPOS | HIB_CLICKABLE | HIB_UPARROW );
110     m_aPasswordsLB.InsertHeaderItem( 2, CUI_RESSTR( STR_USERNAME ),
111         HIB_LEFT | HIB_VCENTER | HIB_FIXEDPOS );
112     m_aPasswordsLB.ResetTabs();
113 
114     FreeResource();
115 
116     m_aPasswordsLB.SetHeaderBarClickHdl( LINK( this, WebConnectionInfoDialog, HeaderBarClickedHdl ) );
117     m_aRemoveBtn.SetClickHdl( LINK( this, WebConnectionInfoDialog, RemovePasswordHdl ) );
118     m_aRemoveAllBtn.SetClickHdl( LINK( this, WebConnectionInfoDialog, RemoveAllPasswordsHdl ) );
119     m_aChangeBtn.SetClickHdl( LINK( this, WebConnectionInfoDialog, ChangePasswordHdl ) );
120 
121     // one button too small for its text?
122     sal_Int32 i = 0;
123     long nBtnTextWidth = 0;
124     Window* pButtons[] = { &m_aRemoveBtn, &m_aRemoveAllBtn, &m_aChangeBtn };
125     Window** pButton = pButtons;
126     const sal_Int32 nBCount = sizeof( pButtons ) / sizeof( pButtons[ 0 ] );
127     for ( ; i < nBCount; ++i, ++pButton )
128     {
129         long nTemp = (*pButton)->GetCtrlTextWidth( (*pButton)->GetText() );
130         if ( nTemp > nBtnTextWidth )
131             nBtnTextWidth = nTemp;
132     }
133     nBtnTextWidth = nBtnTextWidth * 115 / 100; // a little offset
134     long nButtonWidth = m_aRemoveBtn.GetSizePixel().Width();
135     if ( nBtnTextWidth > nButtonWidth )
136     {
137         // so make the buttons broader and its control in front of it smaller
138         long nDelta = nBtnTextWidth - nButtonWidth;
139         pButton = pButtons;
140         for ( i = 0; i < nBCount; ++i, ++pButton )
141         {
142             Point aNewPos = (*pButton)->GetPosPixel();
143             if ( &m_aRemoveAllBtn == (*pButton) )
144                 aNewPos.X() += nDelta;
145             else if ( &m_aChangeBtn == (*pButton) )
146                 aNewPos.X() -= nDelta;
147             Size aNewSize = (*pButton)->GetSizePixel();
148             aNewSize.Width() += nDelta;
149             (*pButton)->SetPosSizePixel( aNewPos, aNewSize );
150         }
151     }
152 
153     FillPasswordList();
154 
155     m_aRemoveBtn.SetClickHdl( LINK( this, WebConnectionInfoDialog, RemovePasswordHdl ) );
156     m_aRemoveAllBtn.SetClickHdl( LINK( this, WebConnectionInfoDialog, RemoveAllPasswordsHdl ) );
157     m_aChangeBtn.SetClickHdl( LINK( this, WebConnectionInfoDialog, ChangePasswordHdl ) );
158     m_aPasswordsLB.SetSelectHdl( LINK( this, WebConnectionInfoDialog, EntrySelectedHdl ) );
159 
160     m_aRemoveBtn.Enable( sal_False );
161     m_aChangeBtn.Enable( sal_False );
162 
163     HeaderBarClickedHdl( NULL );
164 }
165 
166 // -----------------------------------------------------------------------
~WebConnectionInfoDialog()167 WebConnectionInfoDialog::~WebConnectionInfoDialog()
168 {
169 }
170 
171 // -----------------------------------------------------------------------
IMPL_LINK(WebConnectionInfoDialog,HeaderBarClickedHdl,SvxSimpleTable *,pTable)172 IMPL_LINK( WebConnectionInfoDialog, HeaderBarClickedHdl, SvxSimpleTable*, pTable )
173 {
174     m_aPasswordsLB.Resort( NULL == pTable );
175     return 0;
176 }
177 
178 // -----------------------------------------------------------------------
FillPasswordList()179 void WebConnectionInfoDialog::FillPasswordList()
180 {
181     try
182     {
183         uno::Reference< task::XMasterPasswordHandling > xMasterPasswd(
184             comphelper::getProcessServiceFactory()->createInstance(
185                 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.task.PasswordContainer" ) ) ),
186             uno::UNO_QUERY );
187 
188         if ( xMasterPasswd.is() && xMasterPasswd->isPersistentStoringAllowed() )
189         {
190             uno::Reference< task::XPasswordContainer > xPasswdContainer( xMasterPasswd, uno::UNO_QUERY_THROW );
191             uno::Reference< task::XInteractionHandler > xInteractionHandler(
192                 comphelper::getProcessServiceFactory()->createInstance(
193                     rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.task.InteractionHandler" ) ) ),
194                 uno::UNO_QUERY_THROW );
195 
196             uno::Sequence< task::UrlRecord > aURLEntries = xPasswdContainer->getAllPersistent( xInteractionHandler );
197             sal_Int32 nCount = 0;
198             for ( sal_Int32 nURLInd = 0; nURLInd < aURLEntries.getLength(); nURLInd++ )
199             {
200                 for ( sal_Int32 nUserInd = 0; nUserInd < aURLEntries[nURLInd].UserList.getLength(); nUserInd++ )
201                 {
202                     ::rtl::OUString aUIEntry( aURLEntries[nURLInd].Url );
203                     aUIEntry += ::rtl::OUString::valueOf( (sal_Unicode)'\t' );
204                     aUIEntry += aURLEntries[nURLInd].UserList[nUserInd].UserName;
205                     SvLBoxEntry* pEntry = m_aPasswordsLB.InsertEntry( aUIEntry );
206                     pEntry->SetUserData( (void*)(nCount++) );
207                 }
208             }
209 
210             // remember pos of first url container entry.
211             m_nPos = nCount;
212 
213             uno::Reference< task::XUrlContainer > xUrlContainer(
214                 xPasswdContainer, uno::UNO_QUERY_THROW );
215 
216             uno::Sequence< rtl::OUString > aUrls
217                 = xUrlContainer->getUrls( sal_True /* OnlyPersistent */ );
218 
219             for ( sal_Int32 nURLIdx = 0; nURLIdx < aUrls.getLength(); nURLIdx++ )
220             {
221                 ::rtl::OUString aUIEntry( aUrls[ nURLIdx ] );
222                 aUIEntry += ::rtl::OUString::valueOf( (sal_Unicode)'\t' );
223                 aUIEntry += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "*" ) );
224                 SvLBoxEntry* pEntry = m_aPasswordsLB.InsertEntry( aUIEntry );
225                 pEntry->SetUserData( (void*)(nCount++) );
226             }
227         }
228     }
229     catch( uno::Exception& )
230     {}
231 }
232 
233 // -----------------------------------------------------------------------
IMPL_LINK(WebConnectionInfoDialog,RemovePasswordHdl,PushButton *,EMPTYARG)234 IMPL_LINK( WebConnectionInfoDialog, RemovePasswordHdl, PushButton*, EMPTYARG )
235 {
236     try
237     {
238         SvLBoxEntry* pEntry = m_aPasswordsLB.GetCurEntry();
239         if ( pEntry )
240         {
241             ::rtl::OUString aURL = m_aPasswordsLB.GetEntryText( pEntry, 0 );
242             ::rtl::OUString aUserName = m_aPasswordsLB.GetEntryText( pEntry, 1 );
243 
244             uno::Reference< task::XPasswordContainer > xPasswdContainer(
245                 comphelper::getProcessServiceFactory()->createInstance(
246                     rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
247                         "com.sun.star.task.PasswordContainer" ) ) ),
248                 uno::UNO_QUERY_THROW );
249 
250             sal_Int32 nPos = (sal_Int32)(sal_IntPtr)pEntry->GetUserData();
251             if ( nPos < m_nPos )
252             {
253                 xPasswdContainer->removePersistent( aURL, aUserName );
254             }
255             else
256             {
257                 uno::Reference< task::XUrlContainer > xUrlContainer(
258                     xPasswdContainer, uno::UNO_QUERY_THROW );
259                 xUrlContainer->removeUrl( aURL );
260             }
261             m_aPasswordsLB.RemoveEntry( pEntry );
262         }
263     }
264     catch( uno::Exception& )
265     {}
266 
267     return 0;
268 }
269 
270 // -----------------------------------------------------------------------
IMPL_LINK(WebConnectionInfoDialog,RemoveAllPasswordsHdl,PushButton *,EMPTYARG)271 IMPL_LINK( WebConnectionInfoDialog, RemoveAllPasswordsHdl, PushButton*, EMPTYARG )
272 {
273     try
274     {
275         uno::Reference< task::XPasswordContainer > xPasswdContainer(
276             comphelper::getProcessServiceFactory()->createInstance(
277                 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
278                     "com.sun.star.task.PasswordContainer" ) ) ),
279             uno::UNO_QUERY_THROW );
280 
281         // should the master password be requested before?
282         xPasswdContainer->removeAllPersistent();
283 
284         uno::Reference< task::XUrlContainer > xUrlContainer(
285             xPasswdContainer, uno::UNO_QUERY_THROW );
286         uno::Sequence< rtl::OUString > aUrls
287             = xUrlContainer->getUrls( sal_True /* OnlyPersistent */ );
288         for ( sal_Int32 nURLIdx = 0; nURLIdx < aUrls.getLength(); nURLIdx++ )
289             xUrlContainer->removeUrl( aUrls[ nURLIdx ] );
290 
291         m_aPasswordsLB.Clear();
292     }
293     catch( uno::Exception& )
294     {}
295 
296     return 0;
297 }
298 
299 // -----------------------------------------------------------------------
IMPL_LINK(WebConnectionInfoDialog,ChangePasswordHdl,PushButton *,EMPTYARG)300 IMPL_LINK( WebConnectionInfoDialog, ChangePasswordHdl, PushButton*, EMPTYARG )
301 {
302     try
303     {
304         SvLBoxEntry* pEntry = m_aPasswordsLB.GetCurEntry();
305         if ( pEntry )
306         {
307             ::rtl::OUString aURL = m_aPasswordsLB.GetEntryText( pEntry, 0 );
308             ::rtl::OUString aUserName = m_aPasswordsLB.GetEntryText( pEntry, 1 );
309 
310             ::comphelper::SimplePasswordRequest* pPasswordRequest
311                   = new ::comphelper::SimplePasswordRequest( task::PasswordRequestMode_PASSWORD_CREATE );
312             uno::Reference< task::XInteractionRequest > rRequest( pPasswordRequest );
313 
314             uno::Reference< task::XInteractionHandler > xInteractionHandler(
315                 comphelper::getProcessServiceFactory()->createInstance(
316                     rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
317                         "com.sun.star.task.InteractionHandler" ) ) ),
318                 uno::UNO_QUERY_THROW );
319             xInteractionHandler->handle( rRequest );
320 
321             if ( pPasswordRequest->isPassword() )
322             {
323                 String aNewPass = pPasswordRequest->getPassword();
324                 uno::Sequence< ::rtl::OUString > aPasswd( 1 );
325                 aPasswd[0] = aNewPass;
326 
327                 uno::Reference< task::XPasswordContainer > xPasswdContainer(
328                     comphelper::getProcessServiceFactory()->createInstance(
329                         rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
330                             "com.sun.star.task.PasswordContainer" ) ) ),
331                     uno::UNO_QUERY_THROW );
332                 xPasswdContainer->addPersistent(
333                     aURL, aUserName, aPasswd, xInteractionHandler );
334             }
335         }
336     }
337     catch( uno::Exception& )
338     {}
339 
340     return 0;
341 }
342 
343 // -----------------------------------------------------------------------
IMPL_LINK(WebConnectionInfoDialog,EntrySelectedHdl,void *,EMPTYARG)344 IMPL_LINK( WebConnectionInfoDialog, EntrySelectedHdl, void*, EMPTYARG )
345 {
346     SvLBoxEntry* pEntry = m_aPasswordsLB.GetCurEntry();
347 	if ( !pEntry )
348     {
349         m_aRemoveBtn.Enable( sal_False );
350         m_aChangeBtn.Enable( sal_False );
351     }
352     else
353 	{
354         m_aRemoveBtn.Enable( sal_True );
355 
356         // url container entries (-> use system credentials) have
357         // no password
358         sal_Int32 nPos = (sal_Int32)(sal_IntPtr)pEntry->GetUserData();
359         m_aChangeBtn.Enable( nPos < m_nPos );
360 	}
361 
362 	return 0;
363 }
364 
365 //........................................................................
366 }   // namespace svx
367 //........................................................................
368 
369