File indexing completed on 2024-06-23 05:14:15
0001 /* -*- mode: c++; c-basic-offset:4 -*- 0002 utils/expiration.cpp 0003 0004 This file is part of Kleopatra, the KDE keymanager 0005 SPDX-FileCopyrightText: 2023 g10 Code GmbH 0006 SPDX-FileContributor: Ingo Klöcker <dev@ingo-kloecker.de> 0007 0008 SPDX-License-Identifier: GPL-2.0-or-later 0009 */ 0010 0011 #include <config-kleopatra.h> 0012 0013 #include "expiration.h" 0014 0015 #include <settings.h> 0016 0017 #include <KDateComboBox> 0018 #include <KLocalizedString> 0019 0020 QDate Kleo::maximumAllowedDate() 0021 { 0022 static const QDate maxAllowedDate{2106, 2, 5}; 0023 return maxAllowedDate; 0024 } 0025 0026 QDate Kleo::minimumExpirationDate() 0027 { 0028 return expirationDateRange().minimum; 0029 } 0030 0031 QDate Kleo::maximumExpirationDate() 0032 { 0033 return expirationDateRange().maximum; 0034 } 0035 0036 Kleo::DateRange Kleo::expirationDateRange() 0037 { 0038 Kleo::DateRange range; 0039 0040 const auto settings = Kleo::Settings{}; 0041 const auto today = QDate::currentDate(); 0042 0043 const auto minimumExpiry = std::max(1, settings.validityPeriodInDaysMin()); 0044 range.minimum = std::min(today.addDays(minimumExpiry), maximumAllowedDate()); 0045 0046 const auto maximumExpiry = settings.validityPeriodInDaysMax(); 0047 if (maximumExpiry >= 0) { 0048 range.maximum = std::min(std::max(today.addDays(maximumExpiry), range.minimum), maximumAllowedDate()); 0049 } 0050 0051 return range; 0052 } 0053 0054 QDate Kleo::defaultExpirationDate(Kleo::ExpirationOnUnlimitedValidity onUnlimitedValidity) 0055 { 0056 QDate expirationDate; 0057 0058 const auto settings = Kleo::Settings{}; 0059 const auto defaultExpirationInDays = settings.validityPeriodInDays(); 0060 if (defaultExpirationInDays > 0) { 0061 expirationDate = QDate::currentDate().addDays(defaultExpirationInDays); 0062 } else if (defaultExpirationInDays < 0 || onUnlimitedValidity == ExpirationOnUnlimitedValidity::InternalDefaultExpiration) { 0063 expirationDate = QDate::currentDate().addYears(3); 0064 } 0065 0066 const auto allowedRange = expirationDateRange(); 0067 expirationDate = std::max(expirationDate, allowedRange.minimum); 0068 if (allowedRange.maximum.isValid()) { 0069 expirationDate = std::min(expirationDate, allowedRange.maximum); 0070 } 0071 0072 return expirationDate; 0073 } 0074 0075 bool Kleo::isValidExpirationDate(const QDate &date) 0076 { 0077 const auto allowedRange = expirationDateRange(); 0078 if (date.isValid()) { 0079 return (date >= allowedRange.minimum // 0080 && ((allowedRange.maximum.isValid() && date <= allowedRange.maximum) // 0081 || (!allowedRange.maximum.isValid() && date <= maximumAllowedDate()))); 0082 } else { 0083 return !allowedRange.maximum.isValid(); 0084 } 0085 } 0086 0087 static QString dateToString(const QDate &date, QWidget *widget) 0088 { 0089 // workaround for QLocale using "yy" way too often for years 0090 // stolen from KDateComboBox 0091 auto locale = widget ? widget->locale() : QLocale{}; 0092 const auto dateFormat = (locale 0093 .dateFormat(QLocale::ShortFormat) // 0094 .replace(QLatin1StringView{"yy"}, QLatin1String{"yyyy"}) 0095 .replace(QLatin1StringView{"yyyyyyyy"}, QLatin1String{"yyyy"})); 0096 return locale.toString(date, dateFormat); 0097 } 0098 0099 static QString validityPeriodHint(const Kleo::DateRange &dateRange, QWidget *widget) 0100 { 0101 // the minimum date is always valid 0102 if (dateRange.maximum.isValid()) { 0103 if (dateRange.maximum == dateRange.minimum) { 0104 return i18nc("@info", "The date cannot be changed."); 0105 } else { 0106 return i18nc("@info ... between <a date> and <another date>.", 0107 "Enter a date between %1 and %2.", 0108 dateToString(dateRange.minimum, widget), 0109 dateToString(dateRange.maximum, widget)); 0110 } 0111 } else { 0112 return i18nc("@info ... between <a date> and <another date>.", 0113 "Enter a date between %1 and %2.", 0114 dateToString(dateRange.minimum, widget), 0115 dateToString(Kleo::maximumAllowedDate(), widget)); 0116 } 0117 } 0118 0119 QString Kleo::validityPeriodHint() 0120 { 0121 return ::validityPeriodHint(expirationDateRange(), nullptr); 0122 } 0123 0124 void Kleo::setUpExpirationDateComboBox(KDateComboBox *dateCB, const Kleo::DateRange &range) 0125 { 0126 const auto dateRange = range.minimum.isValid() ? range : expirationDateRange(); 0127 // enable warning on invalid or not allowed dates 0128 dateCB->setOptions(KDateComboBox::EditDate | KDateComboBox::SelectDate | KDateComboBox::DatePicker | KDateComboBox::DateKeywords 0129 | KDateComboBox::WarnOnInvalid); 0130 const auto hintAndErrorMessage = validityPeriodHint(dateRange, dateCB); 0131 dateCB->setDateRange(dateRange.minimum, dateRange.maximum.isValid() ? dateRange.maximum : maximumAllowedDate(), hintAndErrorMessage, hintAndErrorMessage); 0132 if (dateRange.minimum == dateRange.maximum) { 0133 // only one date is allowed, so that changing it no sense 0134 dateCB->setEnabled(false); 0135 } 0136 dateCB->setToolTip(hintAndErrorMessage); 0137 const QDate today = QDate::currentDate(); 0138 dateCB->setDateMap({ 0139 {today.addYears(3), i18nc("@item:inlistbox", "Three years from now")}, 0140 {today.addYears(2), i18nc("@item:inlistbox", "Two years from now")}, 0141 {today.addYears(1), i18nc("@item:inlistbox", "One year from now")}, 0142 }); 0143 }