9#include <QCryptographicHash>
21 LOG(VB_GENERAL, LOG_WARNING, QString(
"IsValid: Invalid session "
27 LOG(VB_GENERAL, LOG_WARNING, QString(
"IsValid: Invalid session "
34 LOG(VB_GENERAL, LOG_WARNING, QString(
"IsValid: Invalid session "
41 LOG(VB_GENERAL, LOG_WARNING, QString(
"IsValid: Expired session "
72 QByteArray randBytes = QUuid::createUuid().toByteArray();
74 QCryptographicHash::Sha1).toHex();
85 query.
prepare(
"REPLACE INTO user_sessions SET "
86 "sessionToken = :SESSION_TOKEN, "
89 "created = :CREATED, "
90 "lastactive = :LASTACTIVE, "
91 "expires = :EXPIRES");
139 query.
prepare(
"SELECT s.sessiontoken, s.created, s.lastactive, s.expires, "
140 " s.client, u.userid, u.username "
141 "FROM user_sessions s, users u "
142 "WHERE s.userid = u.userid ");
168 if (username.isEmpty())
172 query.
prepare(
"SELECT userid FROM users WHERE username = :USERNAME");
196 const QString &client)
198 QMap<QString, MythUserSession>::iterator it;
201 if (((*it).m_name == username) &&
202 ((*it).m_sessionClient == client))
224 query.
prepare(
"SELECT password_digest FROM users WHERE username = :USERNAME");
231 return query.
value(0).toString();
274 const QByteArray &digest,
275 const QString &client)
277 if (username.isEmpty() || digest.isEmpty() || digest.length() < 32 ||
278 digest.length() > 32)
282 query.
prepare(
"SELECT userid, username FROM users WHERE "
283 "username = :USERNAME AND password_digest = :PWDIGEST");
286 query.
bindValue(
":PWDIGEST", QString(digest));
291 if (query.
size() > 1)
293 LOG(VB_GENERAL, LOG_CRIT,
"LoginUser: Warning, multiple matching user records found.");
310 QString userName = query.
value(1).toString();
315 LOG(VB_GENERAL, LOG_WARNING, QString(
"LoginUser: Failed login attempt for "
316 "user %1").arg(username));
325 const QString &password,
326 const QString &client)
330 return LoginUser(username, digest, client);
337 const QString &userName,
338 const QString &client)
343 session.
m_name = userName;
345 QString clientIdentifier = client;
346 if (clientIdentifier.isEmpty())
348 QString
type =
"Master";
375 if (sessionToken.isEmpty())
379 query.
prepare(
"DELETE FROM user_sessions WHERE "
380 "sessionToken = :SESSION_TOKEN");
381 query.
bindValue(
":SESSION_TOKEN", sessionToken);
394 if (username.isEmpty())
397 QMap<QString, MythUserSession>::iterator it;
402 if (((*it).m_name == username))
418 const QString& password)
422 LOG(VB_GENERAL, LOG_ERR, QString(
"Tried to add an existing user: %1.")
428 insert.
prepare(
"INSERT INTO users SET "
429 "username = :USER_NAME, "
430 "password_digest = :PASSWORD_DIGEST");
431 insert.
bindValue(
":USER_NAME", username);
434 bool bResult = insert.
exec();
448 LOG(VB_GENERAL, LOG_ERR, QString(
"Tried to remove a non-existing "
449 "user: %1.").arg(username));
453 if (username ==
"admin")
455 LOG(VB_GENERAL, LOG_ERR, QString(
"Tried to remove user: %1 (not "
456 "permitted.)").arg(
"admin"));
461 deleteQuery.
prepare(
"DELETE FROM users WHERE " "username = :USER_NAME ");
462 deleteQuery.
bindValue(
":USER_NAME", username);
464 bool bResult = deleteQuery.
exec();
478 const QString& oldPassword,
479 const QString& newPassword)
481 if (newPassword.isEmpty())
483 LOG(VB_GENERAL, LOG_ERR, QString(
"New password is missing."));
489 LOG(VB_GENERAL, LOG_ERR, QString(
"Attempted to update non-existing"
490 " user: %1.").arg(username));
495 if (!oldPassword.isEmpty())
497 QByteArray oldPasswordDigest =
CreateDigest(username, oldPassword);
501 LOG(VB_GENERAL, LOG_ERR, QString(
"Incorrect old password for "
502 "user: %1.").arg(username));
508 update.
prepare(
"UPDATE users SET "
509 "password_digest = :NEW_PASSWORD_DIGEST WHERE "
510 "username = :USER_NAME");
513 update.
bindValue(
":USER_NAME", username);
515 bool bResult = update.
exec();
529 const QString &password)
533 QString plainText = QString(
"%1:MythTV:%2").arg(username, password);
534 QByteArray digest = QCryptographicHash::hash(plainText.toLatin1(),
535 QCryptographicHash::Md5).toHex();
543 const QString& username,
544 const QString& password,
545 const QString& newPassword)
547 bool returnCode =
false;
556 LOG(VB_GENERAL, LOG_ERR, QString(
"Unknown action."));
QSqlQuery wrapper that fetches a DB connection from the connection pool.
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
QVariant value(int i) const
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
QString GetHostName(void)
bool IsMasterBackend(void)
is this the actual MBE process
static void DBError(const QString &where, const MSqlQuery &query)
static bool IsValidUser(const QString &username)
Check if the given user exists but not whether there is a valid session open for them!
void UpdateSession(const QString &sessionToken)
Update the session timestamps.
bool IsValidSession(const QString &sessionToken)
Check if the session token is valid.
void DestroyUserAllSessions(const QString &username)
bool RemoveDigestUser(const QString &username)
static QString GetPasswordDigest(const QString &username)
Load the password digest for comparison in the HTTP Auth code.
bool ChangeDigestUserPassword(const QString &username, const QString &oldPassword, const QString &newPassword)
MythUserSession GetSession(const QString &sessionToken)
Load the session details and return.
static void UnlockSessions()
void LoadSessions(void)
Load the values from the sessions table on startup.
void DestroyUserSession(const QString &sessionToken)
Removes user session from the database and cache.
QMap< QString, MythUserSession > m_sessionList
static QByteArray CreateDigest(const QString &username, const QString &password)
Generate a digest string.
bool ManageDigestUser(DigestUserActions action, const QString &username, const QString &password, const QString &newPassword)
Manage digest user entries.
MythUserSession CreateUserSession(uint userId, const QString &username, const QString &client)
Add new user session to the database and cache.
static void LockSessions()
static bool AddDigestUser(const QString &username, const QString &password)
MythUserSession LoginUser(const QString &username, const QByteArray &digest, const QString &client="")
Login user by digest.
QDateTime m_sessionCreated
bool IsValid(void) const
Check if this session object appears properly constructed, it DOES NOT validate whether it is a valid...
bool Save(void)
Save the session to the database.
QDateTime m_sessionExpires
bool CheckPermission(const QString &context, uint permission)
Check if the user has the given permission in a context.
bool Update(void)
Update session expiry and access times.
QDateTime m_sessionLastActive
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
QDateTime as_utc(const QDateTime &old_dt)
Returns copy of QDateTime with TimeSpec set to UTC.
QDateTime current(bool stripped)
Returns current Date and Time in UTC.