Coverage Report

Created: 2026-04-09 11:41

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sfx2/source/dialog/passwd.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 <officecfg/Office/Common.hxx>
21
#include <sfx2/passwd.hxx>
22
#include <sfx2/sfxresid.hxx>
23
#include <sfx2/strings.hrc>
24
#include <svl/PasswordHelper.hxx>
25
#include <rtl/ustrbuf.hxx>
26
#include <vcl/svapp.hxx>
27
#include <vcl/vclenum.hxx>
28
#include <vcl/weld/Builder.hxx>
29
#include <vcl/weld/Dialog.hxx>
30
#include <vcl/weld/MessageDialog.hxx>
31
#include <vcl/weld/weld.hxx>
32
#include <bitmaps.hlst>
33
34
IMPL_LINK_NOARG(SfxPasswordDialog, EditModifyHdl, weld::Entry&, void)
35
0
{
36
0
    ModifyHdl();
37
0
}
38
39
void SfxPasswordDialog::ModifyHdl()
40
0
{
41
0
    OUString aPassword1Text = m_xPassword1ED->get_text();
42
0
    bool bEnable = aPassword1Text.getLength() >= mnMinLen;
43
0
    if (m_xPassword2ED->get_visible())
44
0
        bEnable = (bEnable && (m_xPassword2ED->get_text().getLength() >= mnMinLen));
45
0
    m_xOKBtn->set_sensitive(bEnable);
46
47
    // if there's a confirm entry, the dialog is being used for setting a password
48
0
    if (m_xConfirm1ED->get_visible())
49
0
    {
50
0
        m_xPassword1StrengthBar->set_percentage(
51
0
            SvPasswordHelper::GetPasswordStrengthPercentage(aPassword1Text));
52
0
        bool bPasswordMeetsPolicy = SvPasswordHelper::PasswordMeetsPolicy(
53
0
            aPassword1Text, moPasswordPolicy);
54
0
        m_xPassword1ED->set_message_type(bPasswordMeetsPolicy ? weld::EntryMessageType::Normal
55
0
                                                              : weld::EntryMessageType::Error);
56
0
        m_xPassword1PolicyLabel->set_visible(!bPasswordMeetsPolicy);
57
0
    }
58
59
    // if there's a confirm entry, the dialog is being used for setting a password
60
0
    if (m_xConfirm2ED->get_visible())
61
0
    {
62
0
        OUString aPassword2Text = m_xPassword2ED->get_text();
63
64
0
        m_xPassword2StrengthBar->set_percentage(
65
0
            SvPasswordHelper::GetPasswordStrengthPercentage(m_xPassword2ED->get_text()));
66
67
        // second password is optional, ignore policy if it is empty
68
0
        bool bPasswordMeetsPolicy
69
0
            = aPassword2Text.isEmpty()
70
0
                  ? true
71
0
                  : SvPasswordHelper::PasswordMeetsPolicy(
72
0
                      aPassword2Text, moPasswordPolicy);
73
0
        m_xPassword2ED->set_message_type(bPasswordMeetsPolicy ? weld::EntryMessageType::Normal
74
0
                                                              : weld::EntryMessageType::Error);
75
0
        m_xPassword2PolicyLabel->set_visible(!bPasswordMeetsPolicy);
76
0
    }
77
0
}
78
79
IMPL_LINK(SfxPasswordDialog, InsertTextHdl, OUString&, rTest, bool)
80
0
{
81
0
    if (!mbAsciiOnly)
82
0
        return true;
83
84
0
    const sal_Unicode* pTest = rTest.getStr();
85
0
    sal_Int32 nLen = rTest.getLength();
86
0
    OUStringBuffer aFilter(nLen);
87
0
    bool bReset = false;
88
0
    for (sal_Int32 i = 0; i < nLen; ++i)
89
0
    {
90
0
        if( *pTest > 0x007f )
91
0
            bReset = true;
92
0
        else
93
0
            aFilter.append(*pTest);
94
0
        ++pTest;
95
0
    }
96
97
0
    if (bReset)
98
0
    {
99
0
        rTest = aFilter.makeStringAndClear();
100
        // upgrade from "Normal" to "Warning" if a invalid letter was
101
        // discarded
102
0
        m_xOnlyAsciiFT->set_label_type(weld::LabelType::Warning);
103
0
    }
104
0
    else
105
0
    {
106
        // tdf#161412: downgrade from "Warning" to "Normal" if a valid
107
        // letter was discarded after an invalid letter.
108
0
        m_xOnlyAsciiFT->set_label_type(weld::LabelType::Normal);
109
0
    }
110
111
0
    return true;
112
0
}
113
114
IMPL_LINK_NOARG(SfxPasswordDialog, OKHdl, weld::Button&, void)
115
0
{
116
0
    if (m_xConfirm1ED->get_visible()
117
0
        && !SvPasswordHelper::PasswordMeetsPolicy(GetPassword(), moPasswordPolicy))
118
0
    {
119
0
        m_xPassword1ED->grab_focus();
120
0
        return;
121
0
    }
122
0
    if (m_xConfirm2ED->get_visible() && !GetPassword2().isEmpty()
123
0
        && !SvPasswordHelper::PasswordMeetsPolicy(GetPassword2(), moPasswordPolicy))
124
0
    {
125
0
        m_xPassword2ED->grab_focus();
126
0
        return;
127
0
    }
128
129
0
    bool bConfirmFailed = bool( mnExtras & SfxShowExtras::CONFIRM ) &&
130
0
                          ( GetConfirm() != GetPassword() );
131
0
    if( ( mnExtras & SfxShowExtras::CONFIRM2 ) && ( m_xConfirm2ED->get_text() != GetPassword2() ) )
132
0
        bConfirmFailed = true;
133
0
    if ( bConfirmFailed )
134
0
    {
135
0
        if (m_xConfirmFailedDialog)
136
0
            m_xConfirmFailedDialog->response(RET_CANCEL);
137
138
0
        m_xConfirmFailedDialog =
139
0
            std::shared_ptr<weld::MessageDialog>(Application::CreateMessageDialog(m_xDialog.get(),
140
0
                                                    VclMessageType::Warning, VclButtonsType::Ok,
141
0
                                                    SfxResId(STR_ERROR_WRONG_CONFIRM)));
142
0
        m_xConfirmFailedDialog->runAsync(m_xConfirmFailedDialog, [this](sal_uInt32 response){
143
0
            m_xConfirm1ED->set_text(OUString());
144
0
            m_xConfirm1ED->grab_focus();
145
0
            m_xConfirmFailedDialog->response(response);
146
0
         });
147
0
    }
148
0
    else
149
0
        m_xDialog->response(RET_OK);
150
0
}
151
152
IMPL_LINK(SfxPasswordDialog, ShowHdl, weld::Toggleable&, rToggleable, void)
153
0
{
154
0
    bool bChecked = rToggleable.get_active();
155
0
    if (&rToggleable == m_xBtn1.get())
156
0
    {
157
0
        if (bChecked)
158
0
        {
159
0
            m_xBtn1->set_from_icon_name(RID_SVXBMP_SHOWPASS);
160
0
            m_xPassword1ED->set_visibility(true);
161
0
            m_xPassword1ED->grab_focus();
162
0
        }
163
0
        else
164
0
        {
165
0
            m_xBtn1->set_from_icon_name(RID_SVXBMP_HIDEPASS);
166
0
            m_xPassword1ED->set_visibility(false);
167
0
            m_xPassword1ED->grab_focus();
168
0
        }
169
0
    }
170
0
    else if (&rToggleable == m_xBtn2.get())
171
0
    {
172
0
        if (bChecked)
173
0
        {
174
0
            m_xBtn2->set_from_icon_name(RID_SVXBMP_SHOWPASS);
175
0
            m_xConfirm1ED->set_visibility(true);
176
0
            m_xConfirm1ED->grab_focus();
177
0
        }
178
0
        else
179
0
        {
180
0
            m_xBtn2->set_from_icon_name(RID_SVXBMP_HIDEPASS);
181
0
            m_xConfirm1ED->set_visibility(false);
182
0
            m_xConfirm1ED->grab_focus();
183
0
        }
184
0
    }
185
0
    else if (&rToggleable == m_xBtn3.get())
186
0
    {
187
0
        if (bChecked)
188
0
        {
189
0
            m_xBtn3->set_from_icon_name(RID_SVXBMP_SHOWPASS);
190
0
            m_xPassword2ED->set_visibility(true);
191
0
            m_xPassword2ED->grab_focus();
192
0
        }
193
0
        else
194
0
        {
195
0
            m_xBtn3->set_from_icon_name(RID_SVXBMP_HIDEPASS);
196
0
            m_xPassword2ED->set_visibility(false);
197
0
            m_xPassword2ED->grab_focus();
198
0
        }
199
0
    }
200
0
    else if (&rToggleable == m_xBtn4.get())
201
0
    {
202
0
        if (bChecked)
203
0
        {
204
0
            m_xBtn4->set_from_icon_name(RID_SVXBMP_SHOWPASS);
205
0
            m_xConfirm2ED->set_visibility(true);
206
0
            m_xConfirm2ED->grab_focus();
207
0
        }
208
0
        else
209
0
        {
210
0
            m_xBtn4->set_from_icon_name(RID_SVXBMP_HIDEPASS);
211
0
            m_xConfirm2ED->set_visibility(false);
212
0
            m_xConfirm2ED->grab_focus();
213
0
        }
214
0
    }
215
0
    else {
216
        // should not reach it
217
0
    }
218
0
}
219
220
// CTOR / DTOR -----------------------------------------------------------
221
222
SfxPasswordDialog::SfxPasswordDialog(weld::Widget* pParent, const OUString* pGroupText)
223
0
    : GenericDialogController(pParent, u"sfx/ui/password.ui"_ustr, u"PasswordDialog"_ustr)
224
0
    , m_xPassword1Box(m_xBuilder->weld_frame(u"password1frame"_ustr))
225
0
    , m_xUserFT(m_xBuilder->weld_label(u"userft"_ustr))
226
0
    , m_xUserED(m_xBuilder->weld_entry(u"usered"_ustr))
227
0
    , m_xPassword1FT(m_xBuilder->weld_label(u"pass1ft"_ustr))
228
0
    , m_xPassword1ED(m_xBuilder->weld_entry(u"pass1ed"_ustr))
229
0
    , m_xPassword1StrengthBar(m_xBuilder->weld_level_bar(u"pass1bar"_ustr))
230
0
    , m_xPassword1PolicyLabel(m_xBuilder->weld_label(u"pass1policylabel"_ustr))
231
0
    , m_xConfirm1FT(m_xBuilder->weld_label(u"confirm1ft"_ustr))
232
0
    , m_xConfirm1ED(m_xBuilder->weld_entry(u"confirm1ed"_ustr))
233
0
    , m_xPassword2Box(m_xBuilder->weld_frame(u"password2frame"_ustr))
234
0
    , m_xPassword2FT(m_xBuilder->weld_label(u"pass2ft"_ustr))
235
0
    , m_xPassword2ED(m_xBuilder->weld_entry(u"pass2ed"_ustr))
236
0
    , m_xPassword2StrengthBar(m_xBuilder->weld_level_bar(u"pass2bar"_ustr))
237
0
    , m_xPassword2PolicyLabel(m_xBuilder->weld_label(u"pass2policylabel"_ustr))
238
0
    , m_xConfirm2FT(m_xBuilder->weld_label(u"confirm2ft"_ustr))
239
0
    , m_xConfirm2ED(m_xBuilder->weld_entry(u"confirm2ed"_ustr))
240
0
    , m_xMinLengthFT(m_xBuilder->weld_label(u"minlenft"_ustr))
241
0
    , m_xOnlyAsciiFT(m_xBuilder->weld_label(u"onlyascii"_ustr))
242
0
    , m_xOKBtn(m_xBuilder->weld_button(u"ok"_ustr))
243
0
    , m_xBtn1(m_xBuilder->weld_toggle_button(u"togglebt1"_ustr))
244
0
    , m_xBtn2(m_xBuilder->weld_toggle_button(u"togglebt2"_ustr))
245
0
    , m_xBtn3(m_xBuilder->weld_toggle_button(u"togglebt3"_ustr))
246
0
    , m_xBtn4(m_xBuilder->weld_toggle_button(u"togglebt4"_ustr))
247
0
    , maMinLenPwdStr(SfxResId(STR_PASSWD_MIN_LEN))
248
0
    , maMinLenPwdStr1(SfxResId(STR_PASSWD_MIN_LEN1))
249
0
    , maEmptyPwdStr(SfxResId(STR_PASSWD_EMPTY))
250
0
    , mnMinLen(5)
251
0
    , mnExtras(SfxShowExtras::NONE)
252
0
    , moPasswordPolicy(officecfg::Office::Common:: Security::Scripting::PasswordPolicy::get())
253
0
    , mbAsciiOnly(false)
254
0
{
255
0
    Link<weld::Entry&,void> aLink = LINK(this, SfxPasswordDialog, EditModifyHdl);
256
0
    m_xPassword1ED->connect_changed(aLink);
257
0
    m_xPassword2ED->connect_changed(aLink);
258
0
    Link<OUString&,bool> aLink2 = LINK(this, SfxPasswordDialog, InsertTextHdl);
259
0
    m_xPassword1ED->connect_insert_text(aLink2);
260
0
    m_xPassword2ED->connect_insert_text(aLink2);
261
0
    m_xConfirm1ED->connect_insert_text(aLink2);
262
0
    m_xConfirm2ED->connect_insert_text(aLink2);
263
0
    m_xOKBtn->connect_clicked(LINK(this, SfxPasswordDialog, OKHdl));
264
265
0
    Link<weld::Toggleable&, void> aToggleLink = LINK(this, SfxPasswordDialog, ShowHdl);
266
0
    m_xBtn1->connect_toggled(aToggleLink);
267
0
    m_xBtn2->connect_toggled(aToggleLink);
268
0
    m_xBtn3->connect_toggled(aToggleLink);
269
0
    m_xBtn4->connect_toggled(aToggleLink);
270
271
0
    if(moPasswordPolicy)
272
0
    {
273
0
        m_xPassword1PolicyLabel->set_label(
274
0
            officecfg::Office::Common::Security::Scripting::PasswordPolicyErrorMessage::get());
275
0
        m_xPassword2PolicyLabel->set_label(
276
0
            officecfg::Office::Common::Security::Scripting::PasswordPolicyErrorMessage::get());
277
0
    }
278
279
0
    if (pGroupText)
280
0
        m_xPassword1Box->set_label(*pGroupText);
281
282
    //set the text to the password length
283
0
    SetPasswdText();
284
0
}
285
286
void SfxPasswordDialog::SetPasswdText( )
287
0
{
288
    //set the new string to the minimum password length
289
0
    if (mnMinLen == 0)
290
0
        m_xMinLengthFT->set_label(maEmptyPwdStr);
291
0
    else
292
0
    {
293
0
        if( mnMinLen == 1 )
294
0
            m_xMinLengthFT->set_label(maMinLenPwdStr1);
295
0
        else
296
0
        {
297
0
            maMainPwdStr = maMinLenPwdStr;
298
0
            maMainPwdStr = maMainPwdStr.replaceAll( "$(MINLEN)", OUString::number(static_cast<sal_Int32>(mnMinLen) ) );
299
0
            m_xMinLengthFT->set_label(maMainPwdStr);
300
0
        }
301
0
    }
302
0
}
303
304
305
void SfxPasswordDialog::SetMinLen( sal_uInt16 nLen )
306
0
{
307
0
    mnMinLen = nLen;
308
0
    SetPasswdText();
309
0
    ModifyHdl();
310
0
}
311
312
void SfxPasswordDialog::ShowMinLengthText(bool bShow)
313
0
{
314
0
    m_xMinLengthFT->set_visible(bShow);
315
0
}
316
317
void SfxPasswordDialog::AllowAsciiOnly()
318
0
{
319
0
    mbAsciiOnly = true;
320
0
    m_xOnlyAsciiFT->show();
321
0
}
322
323
void SfxPasswordDialog::PreRun()
324
0
{
325
0
    m_xUserFT->hide();
326
0
    m_xUserED->hide();
327
0
    m_xConfirm1FT->hide();
328
0
    m_xConfirm1ED->hide();
329
0
    m_xPassword1StrengthBar->hide();
330
0
    m_xPassword1FT->hide();
331
0
    m_xPassword2Box->hide();
332
0
    m_xPassword2FT->hide();
333
0
    m_xPassword2ED->hide();
334
0
    m_xPassword2FT->hide();
335
0
    m_xConfirm2FT->hide();
336
0
    m_xConfirm2ED->hide();
337
0
    m_xPassword2StrengthBar->hide();
338
0
    m_xBtn2->hide();
339
0
    m_xBtn3->hide();
340
0
    m_xBtn4->hide();
341
342
0
    if (mnExtras != SfxShowExtras::NONE)
343
0
        m_xPassword1FT->show();
344
0
    if (mnExtras & SfxShowExtras::USER)
345
0
    {
346
0
        m_xUserFT->show();
347
0
        m_xUserED->show();
348
0
    }
349
0
    if (mnExtras & SfxShowExtras::CONFIRM)
350
0
    {
351
0
        m_xConfirm1FT->show();
352
0
        m_xConfirm1ED->show();
353
0
        m_xPassword1StrengthBar->show();
354
0
        m_xBtn2->show();
355
0
    }
356
0
    if (mnExtras & SfxShowExtras::PASSWORD2)
357
0
    {
358
0
        m_xPassword2Box->show();
359
0
        m_xPassword2FT->show();
360
0
        m_xPassword2ED->show();
361
0
        m_xBtn3->show();
362
0
    }
363
0
    if (mnExtras & SfxShowExtras::CONFIRM2)
364
0
    {
365
0
        m_xConfirm2FT->show();
366
0
        m_xConfirm2ED->show();
367
0
        m_xPassword2StrengthBar->show();
368
0
        m_xBtn4->show();
369
0
    }
370
0
}
371
372
short SfxPasswordDialog::run()
373
0
{
374
0
    PreRun();
375
376
0
    return GenericDialogController::run();
377
0
}
378
379
SfxPasswordDialog::~SfxPasswordDialog()
380
0
{
381
0
    if (m_xConfirmFailedDialog)
382
0
        m_xConfirmFailedDialog->response(RET_CANCEL);
383
0
}
384
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */