Added authentication backends: internal, pam and http-headers. fixes #119

This commit is contained in:
emeric
2021-03-04 19:32:09 +01:00
parent b94fe3e852
commit cc28d893f5
73 changed files with 2208 additions and 1254 deletions
+39 -32
View File
@@ -22,6 +22,7 @@
#include <map>
#include <mutex>
#include <thread>
#include <string_view>
#include "utils/Exception.hpp"
#include "utils/Logger.hpp"
@@ -40,17 +41,16 @@
namespace Database {
#define LMS_DATABASE_VERSION 28
using Version = std::size_t;
static constexpr Version LMS_DATABASE_VERSION {29};
using Version = std::size_t;
class VersionInfo
{
public:
using pointer = Wt::Dbo::ptr<VersionInfo>;
class VersionInfo
{
public:
using pointer = Wt::Dbo::ptr<VersionInfo>;
static VersionInfo::pointer getOrCreate(Session& session)
{
static VersionInfo::pointer getOrCreate(Session& session)
{
session.checkUniqueLocked();
pointer versionInfo {session.getDboSession().find<VersionInfo>()};
@@ -270,7 +270,7 @@ CREATE TABLE "user_backup" (
else if (version == 24)
{
// User's AuthMode
_session.execute("ALTER TABLE user ADD auth_mode INTEGER NOT NULL DEFAULT(" + std::to_string(static_cast<int>(User::defaultAuthMode)) + ")");
_session.execute("ALTER TABLE user ADD auth_mode INTEGER NOT NULL DEFAULT(" + std::to_string(static_cast<int>(/*User::defaultAuthMode*/0)) + ")");
}
else if (version == 25)
{
@@ -290,6 +290,31 @@ CREATE TABLE "user_backup" (
// Just increment the scan version of the settings to make the next scheduled scan rescan everything
ScanSettings::get(*this).modify()->incScanVersion();
}
else if (version == 28)
{
// Drop Auth mode
_session.execute(R"(
CREATE TABLE "user_backup" (
"id" integer primary key autoincrement,
"version" integer not null,
"type" integer not null,
"login_name" text not null,
"password_salt" text not null,
"password_hash" text not null,
"last_login" text,
"subsonic_transcode_enable" boolean not null,
"subsonic_transcode_format" integer not null,
"subsonic_transcode_bitrate" integer not null,
"subsonic_artist_list_mode" integer not null,
"ui_theme" integer not null,
"cur_playing_track_pos" integer not null,
"repeat_all" boolean not null,
"radio" boolean not null
))");
_session.execute("INSERT INTO user_backup SELECT id, version, type, login_name, password_salt, password_hash, last_login, subsonic_transcode_enable, subsonic_transcode_format, subsonic_transcode_bitrate, subsonic_artist_list_mode, ui_theme, cur_playing_track_pos, repeat_all, radio FROM user");
_session.execute("DROP TABLE user");
_session.execute("ALTER TABLE user_backup RENAME TO user");
}
else
{
LMS_LOG(DB, ERROR) << "Database version " << version << " cannot be handled using migration";
@@ -329,46 +354,28 @@ enum class OwnedLock
Unique,
};
static thread_local std::map<std::shared_mutex*, OwnedLock> lockDebug;
UniqueTransaction::UniqueTransaction(std::shared_mutex& mutex, Wt::Dbo::Session& session)
UniqueTransaction::UniqueTransaction(RecursiveSharedMutex& mutex, Wt::Dbo::Session& session)
: _lock {mutex},
_transaction {session}
{
assert(lockDebug[_lock.mutex()] == OwnedLock::None);
lockDebug[_lock.mutex()] = OwnedLock::Unique;
}
UniqueTransaction::~UniqueTransaction()
{
assert(lockDebug[_lock.mutex()] == OwnedLock::Unique);
lockDebug[_lock.mutex()] = OwnedLock::None;
}
SharedTransaction::SharedTransaction(std::shared_mutex& mutex, Wt::Dbo::Session& session)
SharedTransaction::SharedTransaction(RecursiveSharedMutex& mutex, Wt::Dbo::Session& session)
: _lock {mutex},
_transaction {session}
{
assert(lockDebug[_lock.mutex()] == OwnedLock::None);
lockDebug[_lock.mutex()] = OwnedLock::Shared;
}
SharedTransaction::~SharedTransaction()
{
assert(lockDebug[_lock.mutex()] == OwnedLock::Shared);
lockDebug[_lock.mutex()] = OwnedLock::None;
}
void
Session::checkUniqueLocked()
{
assert(lockDebug[&_db.getMutex()] == OwnedLock::Unique);
// assert(lockDebug[&_db.getMutex()] == OwnedLock::Unique);
}
void
Session::checkSharedLocked()
{
assert(lockDebug[&_db.getMutex()] != OwnedLock::None);
// assert(lockDebug[&_db.getMutex()] != OwnedLock::None);
}
UniqueTransaction
@@ -0,0 +1,33 @@
/*
* Copyright (C) 2021 Emeric Poupon
*
* This file is part of LMS.
*
* LMS is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* LMS is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with LMS. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
namespace Wt::Dbo
{
template<>
struct sql_value_traits<std::string_view>
{
static void bind(std::string_view str, SqlStatement *statement, int column, int /* size */)
{
statement->bind(column, std::string {str});
}
};
}
+12 -3
View File
@@ -25,6 +25,7 @@
#include "database/Track.hpp"
#include "database/TrackList.hpp"
#include "utils/Logger.hpp"
#include "StringViewTraits.hpp"
namespace Database {
@@ -70,7 +71,7 @@ AuthToken::getByValue(Session& session, const std::string& value)
static const std::string playedListName {"__played_tracks__"};
static const std::string queuedListName {"__queued_tracks__"};
User::User(const std::string& loginName)
User::User(std::string_view loginName)
: _loginName {loginName}
{
}
@@ -93,8 +94,16 @@ User::getDemo(Session& session)
return res;
}
std::size_t
User::getCount(Session& session)
{
session.checkSharedLocked();
return session.getDboSession().query<int>("SELECT COUNT(*) FROM user");
}
User::pointer
User::create(Session& session, const std::string& loginName)
User::create(Session& session, std::string_view loginName)
{
session.checkUniqueLocked();
@@ -115,7 +124,7 @@ User::getById(Session& session, IdType id)
}
User::pointer
User::getByLoginName(Session& session, const std::string& name)
User::getByLoginName(Session& session, std::string_view name)
{
return session.getDboSession().find<User>()
.where("login_name = ?").bind(name);