Version 3.6.0.4, tag libreoffice-3.6.0.4
[LibreOffice.git] / uui / source / passwordcontainer.cxx
blob2b2483216b21d9d7ed79442811867f03bef32fef
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 #include "cppuhelper/factory.hxx"
31 #include "com/sun/star/lang/XMultiServiceFactory.hpp"
32 #include "com/sun/star/task/NoMasterException.hpp"
33 #include "com/sun/star/task/XInteractionHandler.hpp"
34 #include "com/sun/star/task/XMasterPasswordHandling.hpp"
35 #include "com/sun/star/task/XPasswordContainer.hpp"
36 #include "com/sun/star/task/XUrlContainer.hpp"
37 #include "com/sun/star/ucb/AuthenticationRequest.hpp"
38 #include "com/sun/star/ucb/URLAuthenticationRequest.hpp"
39 #include "com/sun/star/ucb/XInteractionSupplyAuthentication.hpp"
40 #include "com/sun/star/ucb/XInteractionSupplyAuthentication2.hpp"
42 #include "passwordcontainer.hxx"
44 using namespace com::sun::star;
46 namespace {
48 //=========================================================================
49 bool fillContinuation(
50 bool bUseSystemCredentials,
51 const ucb::AuthenticationRequest & rRequest,
52 const task::UrlRecord & aRec,
53 const uno::Reference< ucb::XInteractionSupplyAuthentication > &
54 xSupplyAuthentication,
55 const uno::Reference< ucb::XInteractionSupplyAuthentication2 > &
56 xSupplyAuthentication2,
57 bool bCanUseSystemCredentials,
58 bool bCheckForEqualPasswords )
60 if ( bUseSystemCredentials )
62 // "use system creds" record found.
63 // Wants client that we use it?
64 if ( xSupplyAuthentication2.is() && bCanUseSystemCredentials )
66 xSupplyAuthentication2->setUseSystemCredentials( sal_True );
67 return true;
69 return false;
71 else if (aRec.UserList.getLength() != 0)
73 if (aRec.UserList[0].Passwords.getLength() == 0)
75 // Password sequence can be empty, for instance if master
76 // password was not given (e.g. master pw dialog canceled)
77 // pw container does not throw NoMasterException in this case.
78 // bug???
79 return false;
82 // "user/pass" record found.
83 if (!bCheckForEqualPasswords || !rRequest.HasPassword
84 || rRequest.Password != aRec.UserList[0].Passwords[0]) // failed login attempt?
86 if (xSupplyAuthentication->canSetUserName())
87 xSupplyAuthentication->
88 setUserName(aRec.UserList[0].UserName.getStr());
90 if (xSupplyAuthentication->canSetPassword())
91 xSupplyAuthentication->
92 setPassword(aRec.UserList[0].Passwords[0].getStr());
93 if (aRec.UserList[0].Passwords.getLength() > 1)
95 if (rRequest.HasRealm)
97 if (xSupplyAuthentication->canSetRealm())
98 xSupplyAuthentication->
99 setRealm(aRec.UserList[0].Passwords[1].
100 getStr());
102 else if (xSupplyAuthentication->canSetAccount())
103 xSupplyAuthentication->
104 setAccount(aRec.UserList[0].Passwords[1].
105 getStr());
108 if ( xSupplyAuthentication2.is() && bCanUseSystemCredentials )
109 xSupplyAuthentication2->setUseSystemCredentials( sal_False );
111 return true;
114 return false;
117 } // namespace
119 namespace uui {
121 //=========================================================================
122 PasswordContainerHelper::PasswordContainerHelper(
123 uno::Reference< lang::XMultiServiceFactory > const & xServiceFactory )
125 OSL_ENSURE(xServiceFactory.is(), "no service factory given!");
126 if (xServiceFactory.is())
129 m_xPasswordContainer
130 = uno::Reference< task::XPasswordContainer >(
131 xServiceFactory->
132 createInstance(
133 rtl::OUString(
134 RTL_CONSTASCII_USTRINGPARAM(
135 "com.sun.star.task.PasswordContainer"))),
136 uno::UNO_QUERY);
138 catch (uno::Exception const &)
140 OSL_ENSURE(m_xPasswordContainer.is(),
141 "unable to instanciate password container service");
144 //=========================================================================
145 bool PasswordContainerHelper::handleAuthenticationRequest(
146 ucb::AuthenticationRequest const & rRequest,
147 uno::Reference< ucb::XInteractionSupplyAuthentication > const &
148 xSupplyAuthentication,
149 rtl::OUString const & rURL,
150 uno::Reference< task::XInteractionHandler > const & xIH )
151 SAL_THROW((uno::RuntimeException))
153 // Is continuation even a XInteractionSupplyAuthentication2, which
154 // is derived from XInteractionSupplyAuthentication?
155 uno::Reference< ucb::XInteractionSupplyAuthentication2 >
156 xSupplyAuthentication2(xSupplyAuthentication, uno::UNO_QUERY);
158 sal_Bool bCanUseSystemCredentials = sal_False;
159 if (xSupplyAuthentication2.is())
161 sal_Bool bDefaultUseSystemCredentials;
162 bCanUseSystemCredentials
163 = xSupplyAuthentication2->canUseSystemCredentials(
164 bDefaultUseSystemCredentials );
167 uno::Reference< task::XPasswordContainer > xContainer(
168 m_xPasswordContainer );
169 uno::Reference< task::XUrlContainer > xUrlContainer(
170 m_xPasswordContainer, uno::UNO_QUERY );
171 OSL_ENSURE( xUrlContainer.is(), "Got no XUrlContainer!" );
173 if ( !xContainer.is() || !xUrlContainer.is() )
174 return false;
176 if ( bCanUseSystemCredentials )
178 // Runtime / Persistent info avail for current auth request?
180 rtl::OUString aResult = xUrlContainer->findUrl(
181 rURL.isEmpty() ? rRequest.ServerName : rURL );
182 if ( !aResult.isEmpty() )
184 if ( fillContinuation( true,
185 rRequest,
186 task::UrlRecord(),
187 xSupplyAuthentication,
188 xSupplyAuthentication2,
189 bCanUseSystemCredentials,
190 false ) )
192 return true;
197 // xContainer works with userName passwdSequences pairs:
198 if (rRequest.HasUserName && rRequest.HasPassword)
202 if (rRequest.UserName.isEmpty())
204 task::UrlRecord aRec;
205 if ( !rURL.isEmpty() )
206 aRec = xContainer->find(rURL, xIH);
208 if ( aRec.UserList.getLength() == 0 )
210 // compat: try server name.
211 aRec = xContainer->find(rRequest.ServerName, xIH);
214 if ( fillContinuation( false,
215 rRequest,
216 aRec,
217 xSupplyAuthentication,
218 xSupplyAuthentication2,
219 bCanUseSystemCredentials,
220 false ) )
222 return true;
225 else
227 task::UrlRecord aRec;
228 if ( !rURL.isEmpty() )
229 aRec = xContainer->findForName(
230 rURL, rRequest.UserName, xIH);
232 if ( aRec.UserList.getLength() == 0 )
234 // compat: try server name.
235 aRec = xContainer->findForName(
236 rRequest.ServerName, rRequest.UserName, xIH);
239 if ( fillContinuation( false,
240 rRequest,
241 aRec,
242 xSupplyAuthentication,
243 xSupplyAuthentication2,
244 bCanUseSystemCredentials,
245 true ) )
247 return true;
251 catch (task::NoMasterException const &)
252 {} // user did not enter master password
254 return false;
257 //=========================================================================
258 bool PasswordContainerHelper::addRecord(
259 rtl::OUString const & rURL,
260 rtl::OUString const & rUsername,
261 uno::Sequence< rtl::OUString > const & rPasswords,
262 uno::Reference< task::XInteractionHandler > const & xIH,
263 bool bPersist )
264 SAL_THROW((uno::RuntimeException))
268 if ( !rUsername.isEmpty() )
270 OSL_ENSURE( m_xPasswordContainer.is(),
271 "Got no XPasswordContainer!" );
272 if ( !m_xPasswordContainer.is() )
273 return false;
275 if ( bPersist )
277 uno::Reference< task::XMasterPasswordHandling > xMPH(
278 m_xPasswordContainer, uno::UNO_QUERY_THROW );
280 // If persistent storing of passwords is not yet
281 // allowed, enable it.
282 if ( !xMPH->isPersistentStoringAllowed() )
283 xMPH->allowPersistentStoring( sal_True );
285 m_xPasswordContainer->addPersistent( rURL,
286 rUsername,
287 rPasswords,
288 xIH );
290 else
291 m_xPasswordContainer->add( rURL,
292 rUsername,
293 rPasswords,
294 xIH );
296 else
298 uno::Reference< task::XUrlContainer >
299 xContainer( m_xPasswordContainer, uno::UNO_QUERY );
300 OSL_ENSURE( xContainer.is(), "Got no XUrlContainer!" );
301 if ( !xContainer.is() )
302 return false;
304 xContainer->addUrl( rURL, bPersist );
307 catch ( task::NoMasterException const & )
309 // user did not enter master password
310 return false;
312 return true;
315 //=========================================================================
316 //=========================================================================
317 //=========================================================================
319 PasswordContainerInteractionHandler::PasswordContainerInteractionHandler(
320 const uno::Reference< lang::XMultiServiceFactory >& xSMgr )
321 : m_aPwContainerHelper( xSMgr )
325 //=========================================================================
326 // virtual
327 PasswordContainerInteractionHandler::~PasswordContainerInteractionHandler()
331 //=========================================================================
333 // XServiceInfo methods.
335 //=========================================================================
337 // virtual
338 ::rtl::OUString SAL_CALL
339 PasswordContainerInteractionHandler::getImplementationName()
340 throw ( uno::RuntimeException )
342 return getImplementationName_Static();
345 //=========================================================================
346 // virtual
347 sal_Bool SAL_CALL
348 PasswordContainerInteractionHandler::supportsService(
349 const ::rtl::OUString& ServiceName )
350 throw ( uno::RuntimeException )
352 uno::Sequence< rtl::OUString > aSNL = getSupportedServiceNames();
353 const rtl::OUString * pArray = aSNL.getConstArray();
354 for ( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
356 if ( pArray[ i ] == ServiceName )
357 return sal_True;
359 return sal_False;
362 //=========================================================================
363 // virtual
364 uno::Sequence< ::rtl::OUString > SAL_CALL
365 PasswordContainerInteractionHandler::getSupportedServiceNames()
366 throw ( uno::RuntimeException )
368 return getSupportedServiceNames_Static();
371 //=========================================================================
372 // static
373 rtl::OUString
374 PasswordContainerInteractionHandler::getImplementationName_Static()
376 return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
377 "com.sun.star.comp.uui.PasswordContainerInteractionHandler" ) );
380 //=========================================================================
381 // static
382 uno::Sequence< rtl::OUString >
383 PasswordContainerInteractionHandler::getSupportedServiceNames_Static()
385 uno::Sequence< rtl::OUString > aSNS( 1 );
386 aSNS.getArray()[ 0 ]
387 = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
388 "com.sun.star.task.PasswordContainerInteractionHandler" ) );
389 return aSNS;
392 //=========================================================================
394 // XInteractionHandler methods.
396 //=========================================================================
398 // virtual
399 void SAL_CALL
400 PasswordContainerInteractionHandler::handle(
401 const uno::Reference< task::XInteractionRequest >& rRequest )
402 throw ( uno::RuntimeException )
404 if ( !rRequest.is() )
405 return;
407 uno::Any aAnyRequest( rRequest->getRequest() );
409 ucb::AuthenticationRequest aAuthenticationRequest;
410 if ( !( aAnyRequest >>= aAuthenticationRequest ) )
411 return;
413 rtl::OUString aURL;
414 ucb::URLAuthenticationRequest aURLAuthenticationRequest;
415 if ( aAnyRequest >>= aURLAuthenticationRequest )
416 aURL = aURLAuthenticationRequest.URL;
418 uno::Sequence< uno::Reference< task::XInteractionContinuation > >
419 rContinuations = rRequest->getContinuations();
421 uno::Reference< ucb::XInteractionSupplyAuthentication >
422 xSupplyAuthentication;
424 for ( sal_Int32 i = 0; i < rContinuations.getLength(); ++i )
426 xSupplyAuthentication
427 = uno::Reference< ucb::XInteractionSupplyAuthentication >(
428 rContinuations[i], uno::UNO_QUERY );
429 if( xSupplyAuthentication.is() )
430 break;
433 if ( !xSupplyAuthentication.is() )
434 return;
436 // Try to obtain credentials from password container.
437 if ( m_aPwContainerHelper.
438 handleAuthenticationRequest( aAuthenticationRequest,
439 xSupplyAuthentication,
440 aURL,
441 // @@@ FIXME: this not able to
442 // handle master pw request!
443 // master pw request is never
444 // solvable without UI!
445 this ) )
447 // successfully handled
448 xSupplyAuthentication->select();
452 //=========================================================================
454 // Service factory implementation.
456 //=========================================================================
458 static uno::Reference< uno::XInterface > SAL_CALL
459 PasswordContainerInteractionHandler_CreateInstance(
460 const uno::Reference< lang::XMultiServiceFactory> & rSMgr )
461 throw( uno::Exception )
463 lang::XServiceInfo * pX = static_cast< lang::XServiceInfo * >(
464 new PasswordContainerInteractionHandler( rSMgr ) );
465 return uno::Reference< uno::XInterface >::query( pX );
468 //=========================================================================
469 // static
470 uno::Reference< lang::XSingleServiceFactory >
471 PasswordContainerInteractionHandler::createServiceFactory(
472 const uno::Reference< lang::XMultiServiceFactory >& rxServiceMgr )
474 return uno::Reference< lang::XSingleServiceFactory >(
475 cppu::createOneInstanceFactory(
476 rxServiceMgr,
477 PasswordContainerInteractionHandler::getImplementationName_Static(),
478 PasswordContainerInteractionHandler_CreateInstance,
479 PasswordContainerInteractionHandler::getSupportedServiceNames_Static() ) );
482 } // namespace uui
484 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */