bump product version to 4.1.6.2
[LibreOffice.git] / uui / source / passwordcontainer.cxx
blob1ee48589f9b9d2b9a7efaa175ee0e93e1be88879
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "comphelper/processfactory.hxx"
21 #include "cppuhelper/factory.hxx"
23 #include "com/sun/star/lang/XMultiServiceFactory.hpp"
24 #include "com/sun/star/task/NoMasterException.hpp"
25 #include "com/sun/star/task/PasswordContainer.hpp"
26 #include "com/sun/star/task/XInteractionHandler2.hpp"
27 #include "com/sun/star/ucb/AuthenticationRequest.hpp"
28 #include "com/sun/star/ucb/URLAuthenticationRequest.hpp"
29 #include "com/sun/star/ucb/XInteractionSupplyAuthentication.hpp"
30 #include "com/sun/star/ucb/XInteractionSupplyAuthentication2.hpp"
32 #include "passwordcontainer.hxx"
34 using namespace com::sun::star;
36 namespace {
38 //=========================================================================
39 bool fillContinuation(
40 bool bUseSystemCredentials,
41 const ucb::AuthenticationRequest & rRequest,
42 const task::UrlRecord & aRec,
43 const uno::Reference< ucb::XInteractionSupplyAuthentication > &
44 xSupplyAuthentication,
45 const uno::Reference< ucb::XInteractionSupplyAuthentication2 > &
46 xSupplyAuthentication2,
47 bool bCanUseSystemCredentials,
48 bool bCheckForEqualPasswords )
50 if ( bUseSystemCredentials )
52 // "use system creds" record found.
53 // Wants client that we use it?
54 if ( xSupplyAuthentication2.is() && bCanUseSystemCredentials )
56 xSupplyAuthentication2->setUseSystemCredentials( sal_True );
57 return true;
59 return false;
61 else if (aRec.UserList.getLength() != 0)
63 if (aRec.UserList[0].Passwords.getLength() == 0)
65 // Password sequence can be empty, for instance if master
66 // password was not given (e.g. master pw dialog canceled)
67 // pw container does not throw NoMasterException in this case.
68 // bug???
69 return false;
72 // "user/pass" record found.
73 if (!bCheckForEqualPasswords || !rRequest.HasPassword
74 || rRequest.Password != aRec.UserList[0].Passwords[0]) // failed login attempt?
76 if (xSupplyAuthentication->canSetUserName())
77 xSupplyAuthentication->
78 setUserName(aRec.UserList[0].UserName.getStr());
80 if (xSupplyAuthentication->canSetPassword())
81 xSupplyAuthentication->
82 setPassword(aRec.UserList[0].Passwords[0].getStr());
83 if (aRec.UserList[0].Passwords.getLength() > 1)
85 if (rRequest.HasRealm)
87 if (xSupplyAuthentication->canSetRealm())
88 xSupplyAuthentication->
89 setRealm(aRec.UserList[0].Passwords[1].
90 getStr());
92 else if (xSupplyAuthentication->canSetAccount())
93 xSupplyAuthentication->
94 setAccount(aRec.UserList[0].Passwords[1].
95 getStr());
98 if ( xSupplyAuthentication2.is() && bCanUseSystemCredentials )
99 xSupplyAuthentication2->setUseSystemCredentials( sal_False );
101 return true;
104 return false;
107 } // namespace
109 namespace uui {
111 //=========================================================================
112 PasswordContainerHelper::PasswordContainerHelper(
113 uno::Reference< uno::XComponentContext > const & xContext ):
114 m_xPasswordContainer(task::PasswordContainer::create(xContext))
117 //=========================================================================
118 bool PasswordContainerHelper::handleAuthenticationRequest(
119 ucb::AuthenticationRequest const & rRequest,
120 uno::Reference< ucb::XInteractionSupplyAuthentication > const &
121 xSupplyAuthentication,
122 OUString const & rURL,
123 uno::Reference< task::XInteractionHandler2 > const & xIH )
124 SAL_THROW((uno::RuntimeException))
126 uno::Reference< task::XInteractionHandler > xIH1(xIH, uno::UNO_QUERY);
128 // Is continuation even a XInteractionSupplyAuthentication2, which
129 // is derived from XInteractionSupplyAuthentication?
130 uno::Reference< ucb::XInteractionSupplyAuthentication2 >
131 xSupplyAuthentication2(xSupplyAuthentication, uno::UNO_QUERY);
133 sal_Bool bCanUseSystemCredentials = sal_False;
134 if (xSupplyAuthentication2.is())
136 sal_Bool bDefaultUseSystemCredentials;
137 bCanUseSystemCredentials
138 = xSupplyAuthentication2->canUseSystemCredentials(
139 bDefaultUseSystemCredentials );
142 if ( bCanUseSystemCredentials )
144 // Runtime / Persistent info avail for current auth request?
146 OUString aResult = m_xPasswordContainer->findUrl(
147 rURL.isEmpty() ? rRequest.ServerName : rURL );
148 if ( !aResult.isEmpty() )
150 if ( fillContinuation( true,
151 rRequest,
152 task::UrlRecord(),
153 xSupplyAuthentication,
154 xSupplyAuthentication2,
155 bCanUseSystemCredentials,
156 false ) )
158 return true;
163 // m_xPasswordContainer works with userName passwdSequences pairs:
164 if (rRequest.HasUserName && rRequest.HasPassword)
168 if (rRequest.UserName.isEmpty())
170 task::UrlRecord aRec;
171 if ( !rURL.isEmpty() )
172 aRec = m_xPasswordContainer->find(rURL, xIH1);
174 if ( aRec.UserList.getLength() == 0 )
176 // compat: try server name.
177 aRec = m_xPasswordContainer->find(rRequest.ServerName, xIH1);
180 if ( fillContinuation( false,
181 rRequest,
182 aRec,
183 xSupplyAuthentication,
184 xSupplyAuthentication2,
185 bCanUseSystemCredentials,
186 false ) )
188 return true;
191 else
193 task::UrlRecord aRec;
194 if ( !rURL.isEmpty() )
195 aRec = m_xPasswordContainer->findForName(
196 rURL, rRequest.UserName, xIH1);
198 if ( aRec.UserList.getLength() == 0 )
200 // compat: try server name.
201 aRec = m_xPasswordContainer->findForName(
202 rRequest.ServerName, rRequest.UserName, xIH1);
205 if ( fillContinuation( false,
206 rRequest,
207 aRec,
208 xSupplyAuthentication,
209 xSupplyAuthentication2,
210 bCanUseSystemCredentials,
211 true ) )
213 return true;
217 catch (task::NoMasterException const &)
218 {} // user did not enter master password
220 return false;
223 //=========================================================================
224 bool PasswordContainerHelper::addRecord(
225 OUString const & rURL,
226 OUString const & rUsername,
227 uno::Sequence< OUString > const & rPasswords,
228 uno::Reference< task::XInteractionHandler2 > const & xIH,
229 bool bPersist )
230 SAL_THROW((uno::RuntimeException))
232 uno::Reference< task::XInteractionHandler > xIH1(xIH, uno::UNO_QUERY);
236 if ( !rUsername.isEmpty() )
238 OSL_ENSURE( m_xPasswordContainer.is(),
239 "Got no XPasswordContainer!" );
240 if ( !m_xPasswordContainer.is() )
241 return false;
243 if ( bPersist )
245 // If persistent storing of passwords is not yet
246 // allowed, enable it.
247 if ( !m_xPasswordContainer->isPersistentStoringAllowed() )
248 m_xPasswordContainer->allowPersistentStoring( sal_True );
250 m_xPasswordContainer->addPersistent( rURL,
251 rUsername,
252 rPasswords,
253 xIH1 );
255 else
256 m_xPasswordContainer->add( rURL,
257 rUsername,
258 rPasswords,
259 xIH1 );
261 else
263 m_xPasswordContainer->addUrl( rURL, bPersist );
266 catch ( task::NoMasterException const & )
268 // user did not enter master password
269 return false;
271 return true;
274 //=========================================================================
275 //=========================================================================
276 //=========================================================================
278 PasswordContainerInteractionHandler::PasswordContainerInteractionHandler(
279 const uno::Reference< uno::XComponentContext >& xContext )
280 : m_aPwContainerHelper( xContext )
284 //=========================================================================
285 // virtual
286 PasswordContainerInteractionHandler::~PasswordContainerInteractionHandler()
290 //=========================================================================
292 // XServiceInfo methods.
294 //=========================================================================
296 // virtual
297 OUString SAL_CALL
298 PasswordContainerInteractionHandler::getImplementationName()
299 throw ( uno::RuntimeException )
301 return getImplementationName_Static();
304 //=========================================================================
305 // virtual
306 sal_Bool SAL_CALL
307 PasswordContainerInteractionHandler::supportsService(
308 const OUString& ServiceName )
309 throw ( uno::RuntimeException )
311 uno::Sequence< OUString > aSNL = getSupportedServiceNames();
312 const OUString * pArray = aSNL.getConstArray();
313 for ( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
315 if ( pArray[ i ] == ServiceName )
316 return sal_True;
318 return sal_False;
321 //=========================================================================
322 // virtual
323 uno::Sequence< OUString > SAL_CALL
324 PasswordContainerInteractionHandler::getSupportedServiceNames()
325 throw ( uno::RuntimeException )
327 return getSupportedServiceNames_Static();
330 //=========================================================================
331 // static
332 OUString
333 PasswordContainerInteractionHandler::getImplementationName_Static()
335 return OUString( "com.sun.star.comp.uui.PasswordContainerInteractionHandler" );
338 //=========================================================================
339 // static
340 uno::Sequence< OUString >
341 PasswordContainerInteractionHandler::getSupportedServiceNames_Static()
343 uno::Sequence< OUString > aSNS( 1 );
344 aSNS.getArray()[ 0 ] = OUString(
345 "com.sun.star.task.PasswordContainerInteractionHandler" );
346 return aSNS;
349 //=========================================================================
351 // XInteractionHandler2 methods.
353 //=========================================================================
355 // virtual
356 void SAL_CALL
357 PasswordContainerInteractionHandler::handle(
358 const uno::Reference< task::XInteractionRequest >& rRequest )
359 throw ( uno::RuntimeException )
361 handleInteractionRequest( rRequest );
364 // virtual
365 sal_Bool SAL_CALL
366 PasswordContainerInteractionHandler::handleInteractionRequest(
367 const uno::Reference< task::XInteractionRequest >& rRequest )
368 throw ( uno::RuntimeException )
370 if ( !rRequest.is() )
371 return false;
373 uno::Any aAnyRequest( rRequest->getRequest() );
375 ucb::AuthenticationRequest aAuthenticationRequest;
376 if ( !( aAnyRequest >>= aAuthenticationRequest ) )
377 return false;
379 OUString aURL;
380 ucb::URLAuthenticationRequest aURLAuthenticationRequest;
381 if ( aAnyRequest >>= aURLAuthenticationRequest )
382 aURL = aURLAuthenticationRequest.URL;
384 uno::Sequence< uno::Reference< task::XInteractionContinuation > >
385 rContinuations = rRequest->getContinuations();
387 uno::Reference< ucb::XInteractionSupplyAuthentication >
388 xSupplyAuthentication;
390 for ( sal_Int32 i = 0; i < rContinuations.getLength(); ++i )
392 xSupplyAuthentication
393 = uno::Reference< ucb::XInteractionSupplyAuthentication >(
394 rContinuations[i], uno::UNO_QUERY );
395 if( xSupplyAuthentication.is() )
396 break;
399 if ( !xSupplyAuthentication.is() )
400 return false;
402 // Try to obtain credentials from password container.
403 if ( m_aPwContainerHelper.
404 handleAuthenticationRequest( aAuthenticationRequest,
405 xSupplyAuthentication,
406 aURL,
407 // @@@ FIXME: this not able to
408 // handle master pw request!
409 // master pw request is never
410 // solvable without UI!
411 this ) )
413 // successfully handled
414 xSupplyAuthentication->select();
415 return true;
417 return false;
420 //=========================================================================
422 // Service factory implementation.
424 //=========================================================================
426 static uno::Reference< uno::XInterface > SAL_CALL
427 PasswordContainerInteractionHandler_CreateInstance(
428 const uno::Reference< lang::XMultiServiceFactory> & rSMgr )
429 throw( uno::Exception )
431 lang::XServiceInfo * pX = static_cast< lang::XServiceInfo * >(
432 new PasswordContainerInteractionHandler( comphelper::getComponentContext(rSMgr) ) );
433 return uno::Reference< uno::XInterface >::query( pX );
436 //=========================================================================
437 // static
438 uno::Reference< lang::XSingleServiceFactory >
439 PasswordContainerInteractionHandler::createServiceFactory(
440 const uno::Reference< lang::XMultiServiceFactory >& rxServiceMgr )
442 return uno::Reference< lang::XSingleServiceFactory >(
443 cppu::createOneInstanceFactory(
444 rxServiceMgr,
445 PasswordContainerInteractionHandler::getImplementationName_Static(),
446 PasswordContainerInteractionHandler_CreateInstance,
447 PasswordContainerInteractionHandler::getSupportedServiceNames_Static() ) );
450 } // namespace uui
452 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */