MythTV  master
parentalcontrols.cpp
Go to the documentation of this file.
1 #include <map>
2 
3 #include "libmyth/mythcontext.h"
4 #include "libmythbase/mythdate.h"
8 
9 #include "parentalcontrols.h"
10 
11 namespace
12 {
14  {
15  if (pl < ParentalLevel::plNone)
16  return ParentalLevel::plNone;
17  if (pl > ParentalLevel::plHigh)
18  return ParentalLevel::plHigh;
19 
20  return pl;
21  }
22 
24  {
25  ParentalLevel::Level rpl(cpl);
26  switch (cpl)
27  {
29  rpl = ParentalLevel::plLowest; break;
31  rpl = ParentalLevel::plLow; break;
33  rpl = ParentalLevel::plMedium; break;
36  rpl = ParentalLevel::plHigh; break;
37  }
38 
39  return boundedParentalLevel(rpl);
40  }
41 
43  {
44  ParentalLevel::Level rpl(cpl);
45  switch (cpl)
46  {
48  rpl = ParentalLevel::plNone; break;
51  rpl = ParentalLevel::plLowest; break;
53  rpl = ParentalLevel::plLow; break;
55  rpl = ParentalLevel::plMedium; break;
56  }
57 
58  return boundedParentalLevel(rpl);
59  }
60 
62  {
63  return boundedParentalLevel(static_cast<ParentalLevel::Level>(pl));
64  }
65 }
66 
68 {
69 }
70 
72  : m_level(toParentalLevel(pl))
73 {
74 }
75 
77 {
78  *this = rhs;
79 }
80 
82 {
83  if (&rhs != this)
84  {
85  m_level = rhs.m_level;
86  m_hitlimit = rhs.m_hitlimit;
87  }
88 
89  return *this;
90 }
91 
93 {
95  return *this;
96 }
97 
99 {
100  Level last = m_level;
102  if (m_level == last)
103  m_hitlimit = true;
104  return *this;
105 }
106 
108 {
109  m_level = toParentalLevel(m_level + amount);
110  return *this;
111 }
112 
114 {
115  Level prev = m_level;
117  if (m_level == prev)
118  m_hitlimit = true;
119  return *this;
120 }
121 
123 {
124  m_level = toParentalLevel(m_level - amount);
125  return *this;
126 }
127 
129 {
130  return m_level;
131 }
132 
133 bool operator!=(const ParentalLevel &lhs, const ParentalLevel &rhs)
134 {
135  return lhs.GetLevel() != rhs.GetLevel();
136 }
137 
138 bool operator==(const ParentalLevel &lhs, const ParentalLevel &rhs)
139 {
140  return lhs.GetLevel() == rhs.GetLevel();
141 }
142 
143 bool operator<(const ParentalLevel &lhs, const ParentalLevel &rhs)
144 {
145  return lhs.GetLevel() < rhs.GetLevel();
146 }
147 
148 bool operator>(const ParentalLevel &lhs, const ParentalLevel &rhs)
149 {
150  return lhs.GetLevel() > rhs.GetLevel();
151 }
152 
153 bool operator<=(const ParentalLevel &lhs, const ParentalLevel &rhs)
154 {
155  return lhs.GetLevel() <= rhs.GetLevel();
156 }
157 
158 bool operator>=(const ParentalLevel &lhs, const ParentalLevel &rhs)
159 {
160  return lhs.GetLevel() >= rhs.GetLevel();
161 }
162 
163 namespace
164 {
166  {
167  private:
168  using pws = std::map<ParentalLevel::Level, QString>;
169 
170  public:
171  void Add(ParentalLevel::Level level, const QString &password)
172  {
173  m_passwords.insert(pws::value_type(level, password));
174  }
175 
176  QStringList AtOrAbove(ParentalLevel::Level level)
177  {
178  QStringList ret;
179  for (ParentalLevel i = level;
180  i <= ParentalLevel::plHigh && i.good(); ++i)
181  {
182  auto p = m_passwords.find(i.GetLevel());
183  if (p != m_passwords.end() && !p->second.isEmpty())
184  ret.push_back(p->second);
185  }
186 
187  return ret;
188  }
189 
191  {
192  QString ret;
193  for (ParentalLevel i = level;
194  i >= ParentalLevel::plLow && i.good(); --i)
195  {
196  auto p = m_passwords.find(i.GetLevel());
197  if (p != m_passwords.end() && !p->second.isEmpty())
198  {
199  ret = p->second;
200  break;
201  }
202  }
203 
204  return ret;
205  }
206 
207  private:
209  };
210 }
211 
212 class ParentalLevelChangeCheckerPrivate : public QObject
213 {
214  Q_OBJECT
215 
216  public:
217  explicit ParentalLevelChangeCheckerPrivate(QObject *lparent)
218  : QObject(lparent)
219  {
221  gCoreContext->GetSetting("VideoAdminPassword"));
223  gCoreContext->GetSetting("VideoAdminPasswordThree"));
225  gCoreContext->GetSetting("VideoAdminPasswordTwo"));
226  }
227 
229  {
230  m_fromLevel = fromLevel;
231  m_toLevel = toLevel;
232  if (DoCheck())
233  {
234  emit SigDone(true, toLevel);
235  }
236  }
237 
238  signals:
239  // NOLINTNEXTLINE(readability-inconsistent-declaration-parameter-name)
240  void SigDone(bool passwordValid, ParentalLevel::Level toLevel);
241 
242  private:
243  // returns true if no completion is required
244  bool DoCheck()
245  {
246  ParentalLevel which_level(m_toLevel);
247 
248  // No password for level 1 and you can always switch down from your
249  // current level.
250  if (which_level == ParentalLevel::plLowest ||
251  which_level <= ParentalLevel(m_fromLevel))
252  return true;
253 
254  // If there isn't a password at the current level, and
255  // none of the levels below, we are done.
256  // The assumption is that if you password protected lower levels,
257  // and a higher level does not have a password it is something
258  // you've overlooked (rather than intended).
259  if (m_pm.FirstAtOrBelow(which_level.GetLevel()).isEmpty())
260  return true;
261 
262  // See if we recently (and successfully) asked for a password
263  QString last_time_stamp = gCoreContext->GetSetting("VideoPasswordTime");
264  int last_parent_lvl = gCoreContext->GetNumSetting("VideoPasswordLevel",
265  -1);
266 
267  if (last_time_stamp.isEmpty() || last_parent_lvl == -1)
268  {
269  LOG(VB_GENERAL, LOG_ERR,
270  QString("%1: Could not read password/pin time "
271  "stamp. This is only an issue if it "
272  "happens repeatedly.").arg(__FILE__));
273  }
274  else
275  {
276  QDateTime curr_time = MythDate::current();
277  QDateTime last_time = MythDate::fromString(last_time_stamp);
278 
279  if (ParentalLevel(last_parent_lvl) >= which_level &&
280  last_time.secsTo(curr_time) < 120)
281  {
282  // Two minute window
283  last_time_stamp = curr_time.toString(Qt::ISODate);
284  gCoreContext->SaveSetting("VideoPasswordTime", last_time_stamp);
285  return true;
286  }
287  }
288 
289  m_validPasswords = m_pm.AtOrAbove(which_level.GetLevel());
290 
291  // If there isn't a password for this level or higher levels, treat
292  // the next lower password as valid. This is only done so people
293  // cannot lock themselves out of the setup.
294  if (m_validPasswords.empty())
295  {
296  QString pw = m_pm.FirstAtOrBelow(which_level.GetLevel());
297  if (!pw.isEmpty())
298  m_validPasswords.push_back(pw);
299  }
300 
301  // There are no suitable passwords.
302  if (m_validPasswords.empty())
303  return true;
304 
305  // If we got here, there is a password, and there's no backing down.
306  m_passwordOK = false;
307  MythScreenStack *popupStack =
308  GetMythMainWindow()->GetStack("popup stack");
309 
310  auto *pwd = new MythTextInputDialog(popupStack,
311  tr("Parental PIN:"), FilterNone, true);
312 
313  connect(pwd, &MythTextInputDialog::haveResult,
316 
317  if (pwd->Create())
318  popupStack->AddScreen(pwd, false);
319 
320  return false;
321  }
322 
323  private slots:
324  void OnPasswordEntered(const QString& password)
325  {
326  m_passwordOK = false;
327 
328  for (const auto& valid_pwd : std::as_const(m_validPasswords))
329  {
330  if (password != valid_pwd)
331  continue;
332 
333  m_passwordOK = true;
334  QString time_stamp = MythDate::current_iso_string();
335 
336  gCoreContext->SaveSetting("VideoPasswordTime", time_stamp);
337  gCoreContext->SaveSetting("VideoPasswordLevel", m_toLevel);
338 
339  return;
340  }
341  }
342 
344  {
346  }
347 
348  private:
349  bool m_passwordOK {false};
352  PasswordManager m_pm;
353  QStringList m_validPasswords;
354 };
355 
357  : m_private(new ParentalLevelChangeCheckerPrivate(this))
358 {
361 }
362 
364  ParentalLevel::Level toLevel)
365 {
366  m_private->Check(fromLevel, toLevel);
367 }
368 
370  ParentalLevel::Level newLevel)
371 {
372  emit SigResultReady(passwordValid, newLevel);
373 }
374 
375 #include "parentalcontrols.moc"
anonymous_namespace{parentalcontrols.cpp}::toParentalLevel
ParentalLevel::Level toParentalLevel(int pl)
Definition: parentalcontrols.cpp:61
operator==
bool operator==(const ParentalLevel &lhs, const ParentalLevel &rhs)
Definition: parentalcontrols.cpp:138
anonymous_namespace{parentalcontrols.cpp}::PasswordManager::Add
void Add(ParentalLevel::Level level, const QString &password)
Definition: parentalcontrols.cpp:171
parentalcontrols.h
mythscreenstack.h
operator>
bool operator>(const ParentalLevel &lhs, const ParentalLevel &rhs)
Definition: parentalcontrols.cpp:148
anonymous_namespace{parentalcontrols.cpp}::PasswordManager::pws
std::map< ParentalLevel::Level, QString > pws
Definition: parentalcontrols.cpp:168
anonymous_namespace{parentalcontrols.cpp}::prevParentalLevel
ParentalLevel::Level prevParentalLevel(ParentalLevel::Level cpl)
Definition: parentalcontrols.cpp:42
mythdialogbox.h
MythScreenStack
Definition: mythscreenstack.h:16
ParentalLevelChangeCheckerPrivate::m_pm
PasswordManager m_pm
Definition: parentalcontrols.cpp:352
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
ParentalLevelChangeCheckerPrivate::SigDone
void SigDone(bool passwordValid, ParentalLevel::Level toLevel)
ParentalLevel::m_level
Level m_level
Definition: parentalcontrols.h:33
ParentalLevelChangeCheckerPrivate::ParentalLevelChangeCheckerPrivate
ParentalLevelChangeCheckerPrivate(QObject *lparent)
Definition: parentalcontrols.cpp:217
ParentalLevelChangeChecker::m_private
class ParentalLevelChangeCheckerPrivate * m_private
Definition: parentalcontrols.h:60
MythTextInputDialog::haveResult
void haveResult(QString)
ParentalLevelChangeCheckerPrivate::Check
void Check(ParentalLevel::Level fromLevel, ParentalLevel::Level toLevel)
Definition: parentalcontrols.cpp:228
MythDate::current
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:14
operator>=
bool operator>=(const ParentalLevel &lhs, const ParentalLevel &rhs)
Definition: parentalcontrols.cpp:158
anonymous_namespace{parentalcontrols.cpp}::PasswordManager::m_passwords
pws m_passwords
Definition: parentalcontrols.cpp:208
ParentalLevelChangeCheckerPrivate::DoCheck
bool DoCheck()
Definition: parentalcontrols.cpp:244
ParentalLevelChangeChecker::ParentalLevelChangeChecker
ParentalLevelChangeChecker()
Definition: parentalcontrols.cpp:356
ParentalLevel::plLowest
@ plLowest
Definition: parentalcontrols.h:13
mythdate.h
operator!=
bool operator!=(const ParentalLevel &lhs, const ParentalLevel &rhs)
Definition: parentalcontrols.cpp:133
hardwareprofile.config.p
p
Definition: config.py:33
ParentalLevel::plLow
@ plLow
Definition: parentalcontrols.h:13
ParentalLevelChangeCheckerPrivate::OnPasswordExit
void OnPasswordExit()
Definition: parentalcontrols.cpp:343
ParentalLevelChangeCheckerPrivate
Definition: parentalcontrols.cpp:212
anonymous_namespace{parentalcontrols.cpp}::PasswordManager::FirstAtOrBelow
QString FirstAtOrBelow(ParentalLevel::Level level)
Definition: parentalcontrols.cpp:190
ParentalLevel::ParentalLevel
ParentalLevel(Level pl)
Definition: parentalcontrols.cpp:67
ParentalLevel::operator=
ParentalLevel & operator=(const ParentalLevel &rhs)
Definition: parentalcontrols.cpp:81
ParentalLevelChangeCheckerPrivate::m_passwordOK
bool m_passwordOK
Definition: parentalcontrols.cpp:349
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:55
operator<=
bool operator<=(const ParentalLevel &lhs, const ParentalLevel &rhs)
Definition: parentalcontrols.cpp:153
ParentalLevel::plMedium
@ plMedium
Definition: parentalcontrols.h:13
ParentalLevelChangeChecker::SigResultReady
void SigResultReady(bool passwordValid, ParentalLevel::Level newLevel)
FilterNone
@ FilterNone
Definition: mythuitextedit.h:21
ParentalLevel::plNone
@ plNone
Definition: parentalcontrols.h:13
MythCoreContext::GetNumSetting
int GetNumSetting(const QString &key, int defaultval=0)
Definition: mythcorecontext.cpp:916
anonymous_namespace{parentalcontrols.cpp}::boundedParentalLevel
ParentalLevel::Level boundedParentalLevel(ParentalLevel::Level pl)
Definition: parentalcontrols.cpp:13
anonymous_namespace{parentalcontrols.cpp}::nextParentalLevel
ParentalLevel::Level nextParentalLevel(ParentalLevel::Level cpl)
Definition: parentalcontrols.cpp:23
MythDate::fromString
QDateTime fromString(const QString &dtstr)
Converts kFilename && kISODate formats to QDateTime.
Definition: mythdate.cpp:34
operator<
bool operator<(const ParentalLevel &lhs, const ParentalLevel &rhs)
Definition: parentalcontrols.cpp:143
anonymous_namespace{parentalcontrols.cpp}::PasswordManager
Definition: parentalcontrols.cpp:165
ParentalLevel::plHigh
@ plHigh
Definition: parentalcontrols.h:14
anonymous_namespace{parentalcontrols.cpp}::PasswordManager::AtOrAbove
QStringList AtOrAbove(ParentalLevel::Level level)
Definition: parentalcontrols.cpp:176
ParentalLevelChangeChecker::Check
void Check(ParentalLevel::Level fromLevel, ParentalLevel::Level toLevel)
Definition: parentalcontrols.cpp:363
ParentalLevelChangeChecker::OnResultReady
void OnResultReady(bool passwordValid, ParentalLevel::Level newLevel)
Definition: parentalcontrols.cpp:369
ParentalLevel
Definition: parentalcontrols.h:9
ParentalLevel::operator+=
ParentalLevel & operator+=(int amount)
Definition: parentalcontrols.cpp:107
MythDate::ISODate
@ ISODate
Default UTC.
Definition: mythdate.h:17
mythcontext.h
GetMythMainWindow
MythMainWindow * GetMythMainWindow(void)
Definition: mythmainwindow.cpp:104
ParentalLevelChangeCheckerPrivate::m_validPasswords
QStringList m_validPasswords
Definition: parentalcontrols.cpp:353
MythDate::current_iso_string
QString current_iso_string(bool stripped)
Returns current Date and Time in UTC as a string.
Definition: mythdate.cpp:22
ParentalLevel::m_hitlimit
bool m_hitlimit
Definition: parentalcontrols.h:34
MythScreenType::Exiting
void Exiting()
MythMainWindow::GetStack
MythScreenStack * GetStack(const QString &Stackname)
Definition: mythmainwindow.cpp:322
ParentalLevel::operator-=
ParentalLevel & operator-=(int amount)
Definition: parentalcontrols.cpp:122
ParentalLevel::Level
Level
Definition: parentalcontrols.h:12
MythTextInputDialog
Dialog prompting the user to enter a text string.
Definition: mythdialogbox.h:314
MythCoreContext::SaveSetting
void SaveSetting(const QString &key, int newValue)
Definition: mythcorecontext.cpp:885
ParentalLevelChangeCheckerPrivate::m_toLevel
ParentalLevel::Level m_toLevel
Definition: parentalcontrols.cpp:351
ParentalLevel::operator--
ParentalLevel & operator--()
Definition: parentalcontrols.cpp:113
mythmainwindow.h
ParentalLevelChangeCheckerPrivate::m_fromLevel
ParentalLevel::Level m_fromLevel
Definition: parentalcontrols.cpp:350
MythScreenStack::AddScreen
virtual void AddScreen(MythScreenType *screen, bool allowFade=true)
Definition: mythscreenstack.cpp:52
ParentalLevel::GetLevel
Level GetLevel() const
Definition: parentalcontrols.cpp:128
ParentalLevelChangeCheckerPrivate::OnPasswordEntered
void OnPasswordEntered(const QString &password)
Definition: parentalcontrols.cpp:324
MythCoreContext::GetSetting
QString GetSetting(const QString &key, const QString &defaultval="")
Definition: mythcorecontext.cpp:902
ParentalLevel::operator++
ParentalLevel & operator++()
Definition: parentalcontrols.cpp:98