Coverage Report

Created: 2026-04-09 11:41

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/uui/source/iahndl-authentication.cxx
Line
Count
Source
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/*
3
 * This file is part of the LibreOffice project.
4
 *
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/.
8
 *
9
 * This file incorporates work covered by the following license notice:
10
 *
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 .
18
 */
19
20
#include <sal/config.h>
21
22
#include <config_oauth2.h>
23
24
#include <com/sun/star/task/DocumentPasswordRequest.hpp>
25
#include <com/sun/star/task/DocumentPasswordRequest2.hpp>
26
#include <com/sun/star/task/DocumentMSPasswordRequest.hpp>
27
#include <com/sun/star/task/DocumentMSPasswordRequest2.hpp>
28
#include <com/sun/star/task/MasterPasswordRequest.hpp>
29
#include <com/sun/star/task/XInteractionAbort.hpp>
30
#include <com/sun/star/task/XInteractionPassword.hpp>
31
#include <com/sun/star/task/XInteractionPassword2.hpp>
32
#include <com/sun/star/task/XInteractionRetry.hpp>
33
#include <com/sun/star/ucb/XInteractionAuthFallback.hpp>
34
#include <com/sun/star/ucb/XInteractionSupplyAuthentication2.hpp>
35
#include <com/sun/star/ucb/URLAuthenticationRequest.hpp>
36
37
#include <osl/diagnose.h>
38
#include <rtl/digest.h>
39
#include <rtl/ustrbuf.hxx>
40
#include <unotools/resmgr.hxx>
41
#include <vcl/errinf.hxx>
42
#include <vcl/abstdlg.hxx>
43
#include <vcl/svapp.hxx>
44
#include <vcl/vclenum.hxx>
45
#include <vcl/weld/MessageDialog.hxx>
46
#include <sal/log.hxx>
47
#include <comphelper/lok.hxx>
48
49
#include "authfallbackdlg.hxx"
50
#include <strings.hrc>
51
#include "getcontinuations.hxx"
52
#include "passwordcontainer.hxx"
53
#include "loginerr.hxx"
54
#include "logindlg.hxx"
55
#include "masterpasscrtdlg.hxx"
56
#include "masterpassworddlg.hxx"
57
#include "passworddlg.hxx"
58
59
#include "iahndl.hxx"
60
#include "iahndl-oauth2.hxx"
61
62
#include <memory>
63
64
using namespace com::sun::star;
65
66
namespace {
67
68
void
69
executeLoginDialog(
70
    weld::Window* pParent,
71
    LoginErrorInfo & rInfo,
72
    OUString const & rRealm)
73
0
{
74
0
    SolarMutexGuard aGuard;
75
76
0
    bool bAccount = (rInfo.GetFlags() & LOGINERROR_FLAG_MODIFY_ACCOUNT) != 0;
77
0
    bool bSavePassword   = rInfo.GetCanRememberPassword();
78
0
    bool bCanUseSysCreds = rInfo.GetCanUseSystemCredentials();
79
80
0
    LoginFlags nFlags = LoginFlags::NONE;
81
0
    if (rInfo.GetErrorText().isEmpty())
82
0
        nFlags |= LoginFlags::NoErrorText;
83
0
    if (!bAccount)
84
0
        nFlags |= LoginFlags::NoAccount;
85
0
    if (!(rInfo.GetFlags() & LOGINERROR_FLAG_MODIFY_USER_NAME))
86
0
        nFlags |= LoginFlags::UsernameReadonly;
87
88
0
    if (!bSavePassword)
89
0
        nFlags |= LoginFlags::NoSavePassword;
90
91
0
    if (!bCanUseSysCreds)
92
0
        nFlags |= LoginFlags::NoUseSysCreds;
93
94
0
    LoginDialog aDialog(pParent, nFlags, rInfo.GetServer(), rRealm);
95
0
    if (!rInfo.GetErrorText().isEmpty())
96
0
        aDialog.SetErrorText(rInfo.GetErrorText());
97
0
    aDialog.SetName(rInfo.GetUserName());
98
0
    if (bAccount)
99
0
        aDialog.ClearAccount();
100
0
    else
101
0
        aDialog.ClearPassword();
102
0
    aDialog.SetPassword(rInfo.GetPassword());
103
104
0
    if (bSavePassword)
105
0
    {
106
0
        std::locale aLocale(Translate::Create("uui"));
107
0
        aDialog.SetSavePasswordText(
108
0
            Translate::get(rInfo.GetIsRememberPersistent()
109
0
                      ? RID_SAVE_PASSWORD
110
0
                      : RID_KEEP_PASSWORD,
111
0
                  aLocale));
112
113
0
        aDialog.SetSavePassword(rInfo.GetIsRememberPassword());
114
0
    }
115
116
0
    if ( bCanUseSysCreds )
117
0
        aDialog.SetUseSystemCredentials( rInfo.GetIsUseSystemCredentials() );
118
119
0
    if (comphelper::LibreOfficeKit::isActive())
120
0
    {
121
        // Avoid the password dialog popup in the LOK case: it's not async and the "remember
122
        // password" checkbox would not work.
123
0
        rInfo.SetResult(DialogMask::ButtonsCancel);
124
0
    }
125
0
    else
126
0
    {
127
0
        rInfo.SetResult(aDialog.run() == RET_OK ? DialogMask::ButtonsOk :
128
0
                DialogMask::ButtonsCancel);
129
0
    }
130
0
    rInfo.SetUserName(aDialog.GetName());
131
0
    rInfo.SetPassword(aDialog.GetPassword());
132
0
    rInfo.SetAccount(aDialog.GetAccount());
133
0
    rInfo.SetIsRememberPassword(aDialog.IsSavePassword());
134
135
0
    if ( bCanUseSysCreds )
136
0
      rInfo.SetIsUseSystemCredentials( aDialog.IsUseSystemCredentials() );
137
0
}
138
139
void getRememberModes(
140
    uno::Sequence< ucb::RememberAuthentication > const & rRememberModes,
141
    ucb::RememberAuthentication & rPreferredMode,
142
    ucb::RememberAuthentication & rAlternateMode )
143
0
{
144
0
    sal_Int32 nCount = rRememberModes.getLength();
145
0
    OSL_ENSURE( (nCount > 0) && (nCount < 4),
146
0
                "ucb::RememberAuthentication sequence size mismatch!" );
147
0
    if ( nCount == 1 )
148
0
    {
149
0
        rPreferredMode = rAlternateMode = rRememberModes[ 0 ];
150
0
        return;
151
0
    }
152
0
    else
153
0
    {
154
0
        bool bHasRememberModeSession = false;
155
0
        bool bHasRememberModePersistent = false;
156
157
0
        for (const auto& rRememberMode : rRememberModes)
158
0
        {
159
0
            switch ( rRememberMode )
160
0
            {
161
0
            case ucb::RememberAuthentication_NO:
162
0
                break;
163
0
            case ucb::RememberAuthentication_SESSION:
164
0
                bHasRememberModeSession = true;
165
0
                break;
166
0
            case ucb::RememberAuthentication_PERSISTENT:
167
0
                bHasRememberModePersistent = true;
168
0
                break;
169
0
            default:
170
0
                SAL_WARN( "uui", "Unsupported RememberAuthentication value" << static_cast<sal_Int32>(rRememberMode) );
171
0
                break;
172
0
            }
173
0
        }
174
175
0
        if (bHasRememberModePersistent)
176
0
        {
177
0
            rPreferredMode = ucb::RememberAuthentication_PERSISTENT;
178
0
            if (bHasRememberModeSession)
179
0
                rAlternateMode = ucb::RememberAuthentication_SESSION;
180
0
            else
181
0
                rAlternateMode = ucb::RememberAuthentication_NO;
182
0
        }
183
0
        else
184
0
        {
185
0
            rPreferredMode = ucb::RememberAuthentication_SESSION;
186
0
            rAlternateMode = ucb::RememberAuthentication_NO;
187
0
        }
188
0
    }
189
0
}
190
191
void
192
handleAuthenticationRequest_(
193
    weld::Window * pParent,
194
    uno::Reference< task::XInteractionHandler2 > const & xIH,
195
    uno::Reference< uno::XComponentContext > const & xContext,
196
    ucb::AuthenticationRequest const & rRequest,
197
    uno::Sequence< uno::Reference< task::XInteractionContinuation > > const &
198
        rContinuations,
199
    const OUString & rURL)
200
0
{
201
0
    uno::Reference< task::XInteractionRetry > xRetry;
202
0
    uno::Reference< task::XInteractionAbort > xAbort;
203
0
    uno::Reference< ucb::XInteractionSupplyAuthentication >
204
0
        xSupplyAuthentication;
205
0
    uno::Reference< ucb::XInteractionSupplyAuthentication2 >
206
0
        xSupplyAuthentication2;
207
0
    getContinuations(rContinuations, &xRetry, &xAbort, &xSupplyAuthentication);
208
0
    if (xSupplyAuthentication.is())
209
0
        xSupplyAuthentication2.set(xSupplyAuthentication, uno::UNO_QUERY);
210
211
212
    // First, try to obtain credentials from password container service.
213
0
    uui::PasswordContainerHelper aPwContainerHelper(xContext);
214
0
    if (aPwContainerHelper.handleAuthenticationRequest(rRequest,
215
0
                                                       xSupplyAuthentication,
216
0
                                                       rURL,
217
0
                                                       xIH))
218
0
    {
219
0
        xSupplyAuthentication->select();
220
0
        return;
221
0
    }
222
223
224
    // Second, try to obtain credentials from user via password dialog.
225
0
    ucb::RememberAuthentication eDefaultRememberMode
226
0
        = ucb::RememberAuthentication_SESSION;
227
0
    ucb::RememberAuthentication ePreferredRememberMode
228
0
        = eDefaultRememberMode;
229
0
    ucb::RememberAuthentication eAlternateRememberMode
230
0
        = ucb::RememberAuthentication_NO;
231
232
0
    if (xSupplyAuthentication.is())
233
0
    {
234
0
        getRememberModes(
235
0
            xSupplyAuthentication->getRememberPasswordModes(
236
0
                eDefaultRememberMode),
237
0
            ePreferredRememberMode,
238
0
            eAlternateRememberMode);
239
0
    }
240
241
0
    bool bCanUseSystemCredentials;
242
0
    sal_Bool bDefaultUseSystemCredentials;
243
0
    if (xSupplyAuthentication2.is())
244
0
    {
245
0
        bCanUseSystemCredentials
246
0
            = xSupplyAuthentication2->canUseSystemCredentials(
247
0
                bDefaultUseSystemCredentials);
248
0
    }
249
0
    else
250
0
    {
251
0
        bCanUseSystemCredentials = false;
252
0
        bDefaultUseSystemCredentials = false;
253
0
    }
254
255
0
    LoginErrorInfo aInfo;
256
0
    aInfo.SetServer(rRequest.ServerName);
257
0
    if (rRequest.HasAccount)
258
0
        aInfo.SetAccount(rRequest.Account);
259
0
    if (rRequest.HasUserName)
260
0
        aInfo.SetUserName(rRequest.UserName);
261
0
    if (rRequest.HasPassword)
262
0
        aInfo.SetPassword(rRequest.Password);
263
0
    aInfo.SetErrorText(rRequest.Diagnostic);
264
265
0
    aInfo.SetCanRememberPassword(
266
0
        ePreferredRememberMode != eAlternateRememberMode);
267
0
    aInfo.SetIsRememberPassword(
268
0
        ePreferredRememberMode == eDefaultRememberMode);
269
0
    aInfo.SetIsRememberPersistent(
270
0
        ePreferredRememberMode == ucb::RememberAuthentication_PERSISTENT);
271
272
0
    aInfo.SetCanUseSystemCredentials(bCanUseSystemCredentials);
273
0
    aInfo.SetIsUseSystemCredentials( bDefaultUseSystemCredentials );
274
0
    aInfo.SetModifyAccount(rRequest.HasAccount
275
0
                           && xSupplyAuthentication.is()
276
0
                           && xSupplyAuthentication->canSetAccount());
277
0
    aInfo.SetModifyUserName(rRequest.HasUserName
278
0
                            && xSupplyAuthentication.is()
279
0
                            && xSupplyAuthentication->canSetUserName());
280
0
    executeLoginDialog(pParent,
281
0
                       aInfo,
282
0
                       rRequest.HasRealm ? rRequest.Realm : OUString());
283
0
    switch (aInfo.GetResult())
284
0
    {
285
0
    case DialogMask::ButtonsOk:
286
0
        if (xSupplyAuthentication.is())
287
0
        {
288
0
            if (xSupplyAuthentication->canSetUserName())
289
0
                xSupplyAuthentication->setUserName(aInfo.GetUserName());
290
0
            if (xSupplyAuthentication->canSetPassword())
291
0
                xSupplyAuthentication->setPassword(aInfo.GetPassword());
292
293
0
            if (ePreferredRememberMode != eAlternateRememberMode)
294
0
            {
295
                // user had the choice.
296
0
                if (aInfo.GetIsRememberPassword())
297
0
                    xSupplyAuthentication->setRememberPassword(
298
0
                        ePreferredRememberMode);
299
0
                else
300
0
                    xSupplyAuthentication->setRememberPassword(
301
0
                        eAlternateRememberMode);
302
0
            }
303
0
            else
304
0
            {
305
                // user had no choice.
306
0
                xSupplyAuthentication->setRememberPassword(
307
0
                    ePreferredRememberMode);
308
0
            }
309
310
0
            if (rRequest.HasRealm)
311
0
            {
312
0
                if (xSupplyAuthentication->canSetRealm())
313
0
                    xSupplyAuthentication->setRealm(aInfo.GetAccount());
314
0
            }
315
0
            else if (xSupplyAuthentication->canSetAccount())
316
0
                xSupplyAuthentication->setAccount(aInfo.GetAccount());
317
318
0
            if ( xSupplyAuthentication2.is() && bCanUseSystemCredentials )
319
0
                xSupplyAuthentication2->setUseSystemCredentials(
320
0
                    aInfo.GetIsUseSystemCredentials() );
321
322
0
            xSupplyAuthentication->select();
323
0
        }
324
325
326
        // Third, store credentials in password container.
327
328
0
          if ( aInfo.GetIsUseSystemCredentials() )
329
0
          {
330
0
              if (aInfo.GetIsRememberPassword())
331
0
              {
332
0
                  if (!aPwContainerHelper.addRecord(
333
0
                          !rURL.isEmpty() ? rURL : rRequest.ServerName,
334
0
                          OUString(), // empty u/p -> sys creds
335
0
                          uno::Sequence< OUString >(),
336
0
                          xIH,
337
0
                          ePreferredRememberMode
338
0
                              == ucb::RememberAuthentication_PERSISTENT))
339
0
                  {
340
0
                      xSupplyAuthentication->setRememberPassword(
341
0
                          ucb::RememberAuthentication_NO);
342
0
                  }
343
0
              }
344
0
              else if (eAlternateRememberMode
345
0
                           == ucb::RememberAuthentication_SESSION)
346
0
              {
347
0
                  if (!aPwContainerHelper.addRecord(
348
0
                          !rURL.isEmpty() ? rURL : rRequest.ServerName,
349
0
                          OUString(), // empty u/p -> sys creds
350
0
                          uno::Sequence< OUString >(),
351
0
                          xIH,
352
0
                          false /* SESSION */))
353
0
                  {
354
0
                      xSupplyAuthentication->setRememberPassword(
355
0
                          ucb::RememberAuthentication_NO);
356
0
                  }
357
0
              }
358
0
          }
359
          // Empty user name can not be valid:
360
0
          else if (!aInfo.GetUserName().isEmpty())
361
0
          {
362
0
              uno::Sequence< OUString >
363
0
                  aPassList(aInfo.GetAccount().isEmpty() ? 1 : 2);
364
0
              auto pPassList = aPassList.getArray();
365
0
              pPassList[0] = aInfo.GetPassword();
366
0
              if (!aInfo.GetAccount().isEmpty())
367
0
                  pPassList[1] = aInfo.GetAccount();
368
369
0
              if (aInfo.GetIsRememberPassword())
370
0
              {
371
0
                  if (!aPwContainerHelper.addRecord(
372
0
                          !rURL.isEmpty() ? rURL : rRequest.ServerName,
373
0
                          aInfo.GetUserName(),
374
0
                          aPassList,
375
0
                          xIH,
376
0
                          ePreferredRememberMode
377
0
                              == ucb::RememberAuthentication_PERSISTENT))
378
0
                  {
379
0
                      xSupplyAuthentication->setRememberPassword(
380
0
                          ucb::RememberAuthentication_NO);
381
0
                  }
382
0
              }
383
0
              else if (eAlternateRememberMode
384
0
                           == ucb::RememberAuthentication_SESSION)
385
0
              {
386
0
                  if (!aPwContainerHelper.addRecord(
387
0
                          !rURL.isEmpty() ? rURL : rRequest.ServerName,
388
0
                          aInfo.GetUserName(),
389
0
                          aPassList,
390
0
                          xIH,
391
0
                          false /* SESSION */))
392
0
                  {
393
0
                      xSupplyAuthentication->setRememberPassword(
394
0
                          ucb::RememberAuthentication_NO);
395
0
                  }
396
0
              }
397
0
          }
398
0
          break;
399
400
0
    case DialogMask::ButtonsRetry:
401
0
        if (xRetry.is())
402
0
            xRetry->select();
403
0
        break;
404
405
0
    default:
406
0
        if (xAbort.is())
407
0
            xAbort->select();
408
0
        break;
409
0
    }
410
0
}
411
412
void
413
executeMasterPasswordDialog(
414
    weld::Window* pParent,
415
    LoginErrorInfo & rInfo,
416
    task::PasswordRequestMode nMode)
417
0
{
418
0
    OString aMaster;
419
0
    {
420
0
        SolarMutexGuard aGuard;
421
422
0
        std::locale aResLocale(Translate::Create("uui"));
423
0
        if( nMode == task::PasswordRequestMode_PASSWORD_CREATE )
424
0
        {
425
0
            MasterPasswordCreateDialog aDialog(pParent, aResLocale);
426
0
            rInfo.SetResult(aDialog.run()
427
0
                == RET_OK ? DialogMask::ButtonsOk : DialogMask::ButtonsCancel);
428
0
            aMaster = OUStringToOString(
429
0
                aDialog.GetMasterPassword(), RTL_TEXTENCODING_UTF8);
430
0
        }
431
0
        else
432
0
        {
433
0
            if (nMode == css::task::PasswordRequestMode_PASSWORD_REENTER)
434
0
            {
435
0
                OUString aErrorMsg(Translate::get(STR_ERROR_MASTERPASSWORD_WRONG, aResLocale));
436
0
                std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(
437
0
                    pParent, VclMessageType::Warning, VclButtonsType::Ok, aErrorMsg));
438
0
                xErrorBox->run();
439
0
            }
440
441
0
            MasterPasswordDialog aDialog(pParent);
442
0
            rInfo.SetResult(aDialog.run()
443
0
                == RET_OK ? DialogMask::ButtonsOk : DialogMask::ButtonsCancel);
444
0
            aMaster = OUStringToOString(
445
0
                aDialog.GetMasterPassword(), RTL_TEXTENCODING_UTF8);
446
0
        }
447
0
    }
448
449
0
    sal_uInt8 aKey[RTL_DIGEST_LENGTH_MD5];
450
    // FIXME this is subject to the SHA1-bug tdf#114939 - but this
451
    // MasterPassword stuff is just stored in the UserInstallation,
452
    // so no interop concerns
453
0
    rtl_digest_PBKDF2(aKey,
454
0
                      RTL_DIGEST_LENGTH_MD5,
455
0
                      reinterpret_cast< sal_uInt8 const * >(aMaster.getStr()),
456
0
                      aMaster.getLength(),
457
0
                      reinterpret_cast< sal_uInt8 const * >(
458
0
                          "3B5509ABA6BC42D9A3A1F3DAD49E56A51"),
459
0
                      32,
460
0
                      1000);
461
462
0
    OUStringBuffer aBuffer;
463
0
    for (sal_uInt8 i : aKey)
464
0
    {
465
        // match PasswordContainer::DecodePasswords aMasterPasswd.copy(index * 2, 2).toUInt32(16));
466
0
        aBuffer.append(OUString::number(i >> 4, 16) + OUString::number(i & 15, 16));
467
0
    }
468
0
    rInfo.SetPassword(aBuffer.makeStringAndClear());
469
0
}
470
471
void
472
handleMasterPasswordRequest_(
473
    weld::Window * pParent,
474
    task::PasswordRequestMode nMode,
475
    uno::Sequence< uno::Reference< task::XInteractionContinuation > > const &
476
        rContinuations)
477
0
{
478
0
    uno::Reference< task::XInteractionRetry > xRetry;
479
0
    uno::Reference< task::XInteractionAbort > xAbort;
480
0
    uno::Reference< ucb::XInteractionSupplyAuthentication >
481
0
        xSupplyAuthentication;
482
0
    getContinuations(rContinuations, &xRetry, &xAbort, &xSupplyAuthentication);
483
0
    LoginErrorInfo aInfo;
484
485
    // in case of master password a hash code is returned
486
0
    executeMasterPasswordDialog(pParent, aInfo, nMode);
487
488
0
    switch (aInfo.GetResult())
489
0
    {
490
0
    case DialogMask::ButtonsOk:
491
0
        if (xSupplyAuthentication.is())
492
0
        {
493
0
            if (xSupplyAuthentication->canSetPassword())
494
0
                xSupplyAuthentication->setPassword(aInfo.GetPassword());
495
0
            xSupplyAuthentication->select();
496
0
        }
497
0
        break;
498
499
0
    case DialogMask::ButtonsRetry:
500
0
        if (xRetry.is())
501
0
            xRetry->select();
502
0
        break;
503
504
0
    default:
505
0
        if (xAbort.is())
506
0
            xAbort->select();
507
0
        break;
508
0
    }
509
0
}
510
511
void
512
executePasswordDialog(
513
    weld::Window * pParent,
514
    LoginErrorInfo & rInfo,
515
    task::PasswordRequestMode nMode,
516
    const OUString& aDocName,
517
    sal_uInt16 nMaxPasswordLen,
518
    bool bIsPasswordToModify,
519
    bool bIsSimplePasswordRequest )
520
0
{
521
0
    SolarMutexGuard aGuard;
522
523
0
    std::locale aResLocale(Translate::Create("uui"));
524
0
    if( nMode == task::PasswordRequestMode_PASSWORD_CREATE )
525
0
    {
526
0
        if (bIsSimplePasswordRequest)
527
0
        {
528
0
            std::unique_ptr<PasswordDialog> xDialog(new PasswordDialog(pParent, nMode,
529
0
                aResLocale, aDocName, bIsPasswordToModify, bIsSimplePasswordRequest));
530
0
            xDialog->SetMinLen(0);
531
532
0
            rInfo.SetResult(xDialog->run() == RET_OK ? DialogMask::ButtonsOk : DialogMask::ButtonsCancel);
533
0
            rInfo.SetPassword(xDialog->GetPassword());
534
0
        }
535
0
        else
536
0
        {
537
0
            VclAbstractDialogFactory * pFact = VclAbstractDialogFactory::Create();
538
0
            ScopedVclPtr<AbstractPasswordToOpenModifyDialog> const pDialog(
539
0
                pFact->CreatePasswordToOpenModifyDialog(pParent, nMaxPasswordLen, bIsPasswordToModify));
540
541
0
            rInfo.SetResult( pDialog->Execute() == RET_OK ? DialogMask::ButtonsOk : DialogMask::ButtonsCancel );
542
0
            rInfo.SetPassword( pDialog->GetPasswordToOpen() );
543
0
            rInfo.SetPasswordToModify( pDialog->GetPasswordToModify() );
544
0
            rInfo.SetRecommendToOpenReadonly( pDialog->IsRecommendToOpenReadonly() );
545
0
        }
546
0
    }
547
0
    else // enter password or reenter password
548
0
    {
549
0
        if (nMode == task::PasswordRequestMode_PASSWORD_REENTER)
550
0
        {
551
0
            TranslateId pOpenToModifyErrStrId = bIsPasswordToModify
552
0
                                                    ? STR_ERROR_PASSWORD_TO_MODIFY_WRONG
553
0
                                                    : STR_ERROR_PASSWORD_TO_OPEN_WRONG;
554
0
            TranslateId pErrStrId = bIsSimplePasswordRequest ? STR_ERROR_SIMPLE_PASSWORD_WRONG
555
0
                                                             : pOpenToModifyErrStrId;
556
0
            OUString aErrorMsg(Translate::get(pErrStrId, aResLocale));
557
0
            std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(
558
0
                pParent, VclMessageType::Warning, VclButtonsType::Ok, aErrorMsg));
559
0
            xBox->run();
560
0
        }
561
562
0
        std::unique_ptr<PasswordDialog> xDialog(new PasswordDialog(pParent, nMode,
563
0
            aResLocale, aDocName, bIsPasswordToModify, bIsSimplePasswordRequest));
564
0
        xDialog->SetMinLen(0);
565
566
0
        rInfo.SetResult(xDialog->run() == RET_OK ? DialogMask::ButtonsOk : DialogMask::ButtonsCancel);
567
0
        rInfo.SetPassword(bIsPasswordToModify ? OUString() : xDialog->GetPassword());
568
0
        rInfo.SetPasswordToModify(bIsPasswordToModify ? xDialog->GetPassword() : OUString());
569
0
    }
570
0
}
571
572
void
573
handlePasswordRequest_(
574
    weld::Window * pParent,
575
    task::PasswordRequestMode nMode,
576
    uno::Sequence< uno::Reference< task::XInteractionContinuation > > const &
577
        rContinuations,
578
    const OUString& aDocumentName,
579
    sal_uInt16 nMaxPasswordLen,
580
    bool bIsPasswordToModify,
581
    bool bIsSimplePasswordRequest = false )
582
0
{
583
0
    uno::Reference< task::XInteractionRetry > xRetry;
584
0
    uno::Reference< task::XInteractionAbort > xAbort;
585
0
    uno::Reference< task::XInteractionPassword > xPassword;
586
0
    uno::Reference< task::XInteractionPassword2 > xPassword2;
587
0
    getContinuations(rContinuations, &xRetry, &xAbort, &xPassword2, &xPassword);
588
589
0
    if ( xPassword2.is() && !xPassword.is() )
590
0
        xPassword.set( xPassword2, uno::UNO_QUERY_THROW );
591
592
0
    LoginErrorInfo aInfo;
593
594
0
    executePasswordDialog( pParent, aInfo, nMode,
595
0
            aDocumentName, nMaxPasswordLen, bIsPasswordToModify, bIsSimplePasswordRequest );
596
597
0
    switch (aInfo.GetResult())
598
0
    {
599
0
    case DialogMask::ButtonsOk:
600
0
        OSL_ENSURE( !bIsPasswordToModify || xPassword2.is(), "PasswordToModify is requested, but there is no Interaction!" );
601
0
        if (xPassword.is())
602
0
        {
603
0
            if (xPassword2.is())
604
0
            {
605
0
                xPassword2->setPasswordToModify( aInfo.GetPasswordToModify() );
606
0
                xPassword2->setRecommendReadOnly( aInfo.IsRecommendToOpenReadonly() );
607
0
            }
608
609
0
            xPassword->setPassword(aInfo.GetPassword());
610
0
            xPassword->select();
611
0
        }
612
0
        break;
613
614
0
    case DialogMask::ButtonsRetry:
615
0
        if (xRetry.is())
616
0
            xRetry->select();
617
0
        break;
618
619
0
    default:
620
0
        if (xAbort.is())
621
0
            xAbort->select();
622
0
        break;
623
0
    }
624
0
}
625
626
} // namespace
627
628
bool
629
UUIInteractionHelper::handleAuthenticationRequest(
630
    uno::Reference< task::XInteractionRequest > const & rRequest)
631
0
{
632
0
    uno::Any aAnyRequest(rRequest->getRequest());
633
0
    uno::Reference<awt::XWindow> xParent = getParentXWindow();
634
635
0
    ucb::URLAuthenticationRequest aURLAuthenticationRequest;
636
0
    if (aAnyRequest >>= aURLAuthenticationRequest)
637
0
    {
638
0
        handleAuthenticationRequest_(Application::GetFrameWeld(xParent),
639
0
                                     getInteractionHandler(),
640
0
                                     m_xContext,
641
0
                                     aURLAuthenticationRequest,
642
0
                                     rRequest->getContinuations(),
643
0
                                     aURLAuthenticationRequest.URL);
644
0
        return true;
645
0
    }
646
647
0
    ucb::AuthenticationRequest aAuthenticationRequest;
648
0
    if (aAnyRequest >>= aAuthenticationRequest)
649
0
    {
650
0
        handleAuthenticationRequest_(Application::GetFrameWeld(xParent),
651
0
                                     getInteractionHandler(),
652
0
                                     m_xContext,
653
0
                                     aAuthenticationRequest,
654
0
                                     rRequest->getContinuations(),
655
0
                                     OUString());
656
0
        return true;
657
0
    }
658
0
    return false;
659
0
}
660
661
bool
662
UUIInteractionHelper::handleMasterPasswordRequest(
663
    uno::Reference< task::XInteractionRequest > const & rRequest)
664
0
{
665
0
    uno::Any aAnyRequest(rRequest->getRequest());
666
667
0
    task::MasterPasswordRequest aMasterPasswordRequest;
668
0
    if (aAnyRequest >>= aMasterPasswordRequest)
669
0
    {
670
0
        uno::Reference<awt::XWindow> xParent = getParentXWindow();
671
672
0
        handleMasterPasswordRequest_(Application::GetFrameWeld(xParent),
673
0
                                     aMasterPasswordRequest.Mode,
674
0
                                     rRequest->getContinuations());
675
0
        return true;
676
0
    }
677
0
    return false;
678
0
}
679
680
bool
681
UUIInteractionHelper::handlePasswordRequest(
682
    uno::Reference< task::XInteractionRequest > const & rRequest)
683
0
{
684
    // parameters to be filled for the call to handlePasswordRequest_
685
0
    uno::Reference<awt::XWindow> xParent = getParentXWindow();
686
0
    task::PasswordRequestMode nMode = task::PasswordRequestMode_PASSWORD_ENTER;
687
0
    uno::Sequence< uno::Reference< task::XInteractionContinuation > > const aContinuations = rRequest->getContinuations();
688
0
    OUString aDocumentName;
689
0
    sal_uInt16 nMaxPasswordLen  = 0;        // any length
690
0
    bool bIsPasswordToModify    = false;
691
692
0
    bool bDoHandleRequest = false;
693
694
0
    uno::Any aAnyRequest(rRequest->getRequest());
695
696
0
    do
697
0
    {
698
0
        task::DocumentPasswordRequest2 aDocumentPasswordRequest2;
699
0
        if (aAnyRequest >>= aDocumentPasswordRequest2)
700
0
        {
701
0
            nMode               = aDocumentPasswordRequest2.Mode;
702
0
            aDocumentName       = aDocumentPasswordRequest2.Name;
703
0
            bIsPasswordToModify = aDocumentPasswordRequest2.IsRequestPasswordToModify;
704
705
0
            bDoHandleRequest = true;
706
0
            break;  // do
707
0
        }
708
709
0
        task::DocumentPasswordRequest aDocumentPasswordRequest;
710
0
        if (aAnyRequest >>= aDocumentPasswordRequest)
711
0
        {
712
0
            nMode               = aDocumentPasswordRequest.Mode;
713
0
            aDocumentName       = aDocumentPasswordRequest.Name;
714
715
0
            bDoHandleRequest = true;
716
0
            break;  // do
717
0
        }
718
719
0
        task::DocumentMSPasswordRequest2 aDocumentMSPasswordRequest2;
720
0
        if (aAnyRequest >>= aDocumentMSPasswordRequest2)
721
0
        {
722
0
            nMode               = aDocumentMSPasswordRequest2.Mode;
723
0
            aDocumentName       = aDocumentMSPasswordRequest2.Name;
724
0
            nMaxPasswordLen     = 15;
725
0
            bIsPasswordToModify = aDocumentMSPasswordRequest2.IsRequestPasswordToModify;
726
727
0
            bDoHandleRequest = true;
728
0
            break;  // do
729
0
        }
730
731
0
        task::DocumentMSPasswordRequest aDocumentMSPasswordRequest;
732
0
        if (aAnyRequest >>= aDocumentMSPasswordRequest)
733
0
        {
734
0
            nMode               = aDocumentMSPasswordRequest.Mode;
735
0
            aDocumentName       = aDocumentMSPasswordRequest.Name;
736
0
            nMaxPasswordLen     = 15;
737
738
0
            bDoHandleRequest = true;
739
0
            break;  // do
740
0
        }
741
0
    }
742
0
    while (false);
743
744
0
    if (bDoHandleRequest)
745
0
    {
746
0
        handlePasswordRequest_( Application::GetFrameWeld(xParent), nMode, aContinuations,
747
0
                aDocumentName, nMaxPasswordLen, bIsPasswordToModify );
748
0
        return true;
749
0
    }
750
751
0
    task::PasswordRequest aPasswordRequest;
752
0
    if( aAnyRequest >>= aPasswordRequest )
753
0
    {
754
0
        handlePasswordRequest_(Application::GetFrameWeld(xParent),
755
0
                               aPasswordRequest.Mode,
756
0
                               rRequest->getContinuations(),
757
0
                               OUString(),
758
0
                               0     /* sal_uInt16 nMaxPasswordLen */,
759
0
                               false /* bool bIsPasswordToModify */,
760
0
                               true  /* bool bIsSimplePasswordRequest */ );
761
0
        return true;
762
0
    }
763
764
0
    return false;
765
0
}
766
767
void
768
UUIInteractionHelper::handleAuthFallbackRequest( const OUString & instructions,
769
        const OUString & url,
770
        uno::Sequence< uno::Reference< task::XInteractionContinuation > > const & rContinuations )
771
0
{
772
0
    OUString code;
773
#if defined OAUTH2REQUEST_SUPPORTED
774
    if (url.indexOf(OAUTH2_REDIRECT_URI_PREFIX) >= 0)
775
    {
776
        OAuth2Request request(url);
777
        request.run();
778
        code = request.getRetCode();
779
    }
780
    else
781
#endif
782
0
    {
783
0
        uno::Reference<awt::XWindow> xParent = getParentXWindow();
784
0
        AuthFallbackDlg dlg(Application::GetFrameWeld(xParent), instructions, url);
785
0
        if (dlg.run() == RET_OK)
786
0
            code = dlg.GetCode();
787
0
    }
788
0
    uno::Reference< task::XInteractionAbort > xAbort;
789
0
    uno::Reference< ucb::XInteractionAuthFallback > xAuthFallback;
790
0
    getContinuations(rContinuations, &xAbort, &xAuthFallback);
791
792
0
    if (!code.isEmpty() && xAuthFallback.is())
793
0
    {
794
0
        xAuthFallback->setCode(code);
795
0
        xAuthFallback->select( );
796
0
    }
797
0
}
798
799
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */