Insert users into sqlite database
All checks were successful
Run tests / run_tests (push) Successful in 1m32s
All checks were successful
Run tests / run_tests (push) Successful in 1m32s
This commit is contained in:
parent
df0ff3f095
commit
18aac0010c
32
flake.nix
32
flake.nix
|
@ -19,7 +19,9 @@
|
||||||
tests = system:
|
tests = system:
|
||||||
builtins.listToAttrs (builtins.map
|
builtins.listToAttrs (builtins.map
|
||||||
(x: let
|
(x: let
|
||||||
test = import (./tests + "/${x}") {pkgs = import nixpkgs {inherit system;};};
|
test = import (./tests + "/${x}") {
|
||||||
|
pkgs = import nixpkgs {inherit system;};
|
||||||
|
};
|
||||||
in {
|
in {
|
||||||
name = test.name;
|
name = test.name;
|
||||||
value = test.test;
|
value = test.test;
|
||||||
|
@ -38,24 +40,30 @@
|
||||||
in
|
in
|
||||||
pkgs.alejandra
|
pkgs.alejandra
|
||||||
);
|
);
|
||||||
|
|
||||||
nixosModules = rec {
|
nixosModules = rec {
|
||||||
declarative-jellyfin = import ./modules;
|
declarative-jellyfin = import ./modules;
|
||||||
default = declarative-jellyfin;
|
default = declarative-jellyfin;
|
||||||
};
|
};
|
||||||
|
|
||||||
packages = forAllSystems (system: let
|
|
||||||
pkgs = import nixpkgs {inherit system;};
|
|
||||||
in {genhash = import ./modules/pbkdf2-sha512.nix {inherit pkgs;};});
|
|
||||||
|
|
||||||
# Run all tests for all systems
|
# Run all tests for all systems
|
||||||
hydraJobs = forAllSystems tests;
|
hydraJobs = forAllSystems tests;
|
||||||
checks = forAllSystems tests;
|
checks = forAllSystems tests;
|
||||||
devShell.x86_64-linux = let
|
|
||||||
pkgs = import nixpkgs {system = "x86_64-linux";};
|
packages = forAllSystems (
|
||||||
in
|
system: let
|
||||||
pkgs.mkShell {
|
pkgs = import nixpkgs {inherit system;};
|
||||||
buildInputs = with pkgs; [bear gcc nettle];
|
in {genhash = import ./modules/pbkdf2-sha512.nix {inherit pkgs;};}
|
||||||
nativeBuildInputs = [pkgs.nettle];
|
);
|
||||||
};
|
|
||||||
|
devShell = forAllSystems (
|
||||||
|
system: let
|
||||||
|
pkgs = import nixpkgs {inherit system;};
|
||||||
|
in
|
||||||
|
pkgs.mkShell {
|
||||||
|
buildInputs = with pkgs; [bear gcc nettle];
|
||||||
|
nativeBuildInputs = [pkgs.nettle];
|
||||||
|
}
|
||||||
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,10 +2,12 @@
|
||||||
config,
|
config,
|
||||||
lib,
|
lib,
|
||||||
pkgs,
|
pkgs,
|
||||||
|
self,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
with lib; let
|
with lib; let
|
||||||
cfg = config.services.declarative-jellyfin;
|
cfg = config.services.declarative-jellyfin;
|
||||||
|
genhash = import ./pbkdf2-sha512.nix {inherit pkgs;};
|
||||||
toXml' = (import ../lib {nixpkgs = pkgs;}).toXMLGeneric;
|
toXml' = (import ../lib {nixpkgs = pkgs;}).toXMLGeneric;
|
||||||
isStrList = x: all (x: isString x) x;
|
isStrList = x: all (x: isString x) x;
|
||||||
prepass = x:
|
prepass = x:
|
||||||
|
@ -91,20 +93,40 @@ in {
|
||||||
defaultDB = ./default.db;
|
defaultDB = ./default.db;
|
||||||
sq = "${pkgs.sqlite}/bin/sqlite3 \"${path}/${dbname}\" --";
|
sq = "${pkgs.sqlite}/bin/sqlite3 \"${path}/${dbname}\" --";
|
||||||
path = "/var/lib/jellyfin/data";
|
path = "/var/lib/jellyfin/data";
|
||||||
|
options = lib.attrsets.mapAttrsToList (key: value: "${key}") (
|
||||||
|
builtins.removeAttrs (
|
||||||
|
(import ./options/users.nix {inherit lib;}).options.services.declarative-jellyfin.Users.type.getSubOptions []
|
||||||
|
)
|
||||||
|
["HashedPasswordFile" "_module"]
|
||||||
|
);
|
||||||
|
|
||||||
|
subtitleModes = {
|
||||||
|
Default = 0;
|
||||||
|
Always = 1;
|
||||||
|
OnlyForce = 2;
|
||||||
|
None = 3;
|
||||||
|
Smart = 4;
|
||||||
|
};
|
||||||
|
|
||||||
genUser = index: user: let
|
genUser = index: user: let
|
||||||
values =
|
values = builtins.removeAttrs (
|
||||||
builtins.mapAttrs
|
builtins.mapAttrs
|
||||||
(name: value:
|
(
|
||||||
if (isBool value)
|
name: value:
|
||||||
then
|
if (isBool value) # bool -> 1 or 0
|
||||||
if value
|
then
|
||||||
then "1"
|
if value
|
||||||
else "0"
|
then "1"
|
||||||
else if (isNull value)
|
else "0"
|
||||||
then "NULL"
|
else if (isNull value) # null -> NULL
|
||||||
else value)
|
then "NULL"
|
||||||
(user
|
else if (name == "SubtitleMode") # SubtitleMode -> 0 | 1 | 2 | 3 | 4
|
||||||
|
then subtitleModes.${value}
|
||||||
|
else if (isString value)
|
||||||
|
then "'${value}'"
|
||||||
|
else value
|
||||||
|
) (
|
||||||
|
user
|
||||||
// {
|
// {
|
||||||
Id =
|
Id =
|
||||||
if !(isNull user.Id)
|
if !(isNull user.Id)
|
||||||
|
@ -117,22 +139,24 @@ in {
|
||||||
Password =
|
Password =
|
||||||
if !(isNull user.HashedPasswordFile)
|
if !(isNull user.HashedPasswordFile)
|
||||||
then "$(${pkgs.coreutils}/bin/cat \"${user.HashedPasswordFile}\")"
|
then "$(${pkgs.coreutils}/bin/cat \"${user.HashedPasswordFile}\")"
|
||||||
else "$(${self.packages.${pkgs.system}.genhash}/bin/genhash -k \"${user.Password}\" -i 210000 -l 128 -u)";
|
else "$(${genhash}/bin/genhash -k \"${user.Password}\" -i 210000 -l 128 -u)";
|
||||||
});
|
}
|
||||||
|
)
|
||||||
|
) ["HashedPasswordFile"];
|
||||||
in
|
in
|
||||||
/*
|
/*
|
||||||
bash
|
bash
|
||||||
*/
|
*/
|
||||||
''
|
''
|
||||||
if [ -n $(${sq} "SELECT 1 FROM Users WHERE Username = '${user.Username}'") ]; then
|
if [ -n $(${sq} "SELECT 1 FROM Users WHERE Username = '${user.Username}'") ]; then
|
||||||
|
echo "User doesn't exist. creaing new: ${user.Username}" >> /var/log/log.txt
|
||||||
# Create user
|
# Create user
|
||||||
${sq} "INSERT INTO Users (${concatStringsSep ","
|
sql="
|
||||||
(
|
INSERT INTO Users (${concatStringsSep "," options}) VALUES(${concatStringsSep "," (map toString (builtins.attrValues values))})"
|
||||||
builtins.filter (x: x != "HashedPasswordFile")
|
|
||||||
(lib.attrsets.mapAttrsToList (name: value: "${name}")
|
echo "SQL COMMAND: $sql" >> /var/log/log.txt
|
||||||
((import ./options/users.nix {inherit lib;}).options.services.declarative-jellyfin.Users.type.getSubOptions []))
|
res=$(${sq} "$sql")
|
||||||
)}) \\
|
echo "OUT: $res" >> /var/log/log.txt
|
||||||
VALUES(${concatStringsSep "," (map toString (builtins.attrValues values))})"
|
|
||||||
fi
|
fi
|
||||||
'';
|
'';
|
||||||
in
|
in
|
||||||
|
@ -140,9 +164,13 @@ in {
|
||||||
bash
|
bash
|
||||||
*/
|
*/
|
||||||
''
|
''
|
||||||
|
mkdir -p /var/log
|
||||||
|
file /var/log/log.txt
|
||||||
|
|
||||||
mkdir -p ${path}
|
mkdir -p ${path}
|
||||||
# Make sure there is a database
|
# Make sure there is a database
|
||||||
if [ ! -e "${path}/${dbname}" ]; then
|
if [ ! -e "${path}/${dbname}" ]; then
|
||||||
|
echo "No DB found. Copying default..." >> /var/log/log.txt
|
||||||
cp ${defaultDB} "${path}/${dbname}"
|
cp ${defaultDB} "${path}/${dbname}"
|
||||||
chmod 770 "${path}/${dbname}"
|
chmod 770 "${path}/${dbname}"
|
||||||
fi
|
fi
|
||||||
|
@ -151,6 +179,7 @@ in {
|
||||||
if [ -z "$maxIndex" ]; then
|
if [ -z "$maxIndex" ]; then
|
||||||
maxIndex="1"
|
maxIndex="1"
|
||||||
fi
|
fi
|
||||||
|
echo "Max index: $maxIndex" >> /var/log/log.txt
|
||||||
|
|
||||||
${
|
${
|
||||||
concatStringsSep "\n"
|
concatStringsSep "\n"
|
||||||
|
|
|
@ -93,7 +93,7 @@ with lib; {
|
||||||
default = "";
|
default = "";
|
||||||
};
|
};
|
||||||
HashedPasswordFile = mkOption {
|
HashedPasswordFile = mkOption {
|
||||||
type = with types; either path str;
|
type = types.nullOr types.path;
|
||||||
description = ''
|
description = ''
|
||||||
A path to a pbkdf2-sha512 hash
|
A path to a pbkdf2-sha512 hash
|
||||||
in this format [PHC string](https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md).
|
in this format [PHC string](https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md).
|
||||||
|
@ -110,7 +110,7 @@ with lib; {
|
||||||
|
|
||||||
```
|
```
|
||||||
'';
|
'';
|
||||||
default = "";
|
default = null;
|
||||||
example = ''
|
example = ''
|
||||||
# the format is: $<id>[$<param>=<value>(,<param>=<value>)*][$<salt>[$<hash>]]
|
# the format is: $<id>[$<param>=<value>(,<param>=<value>)*][$<salt>[$<hash>]]
|
||||||
$PBKDF2-SHA512$iterations=210000$D12C02D1DD15949D867BCA9971BE9987$67E75CDCD14E7F6FDDF96BAACBE9E84E5197FB9FE454FB039F5CD773D7DF558B57DC81DB42B6F7CF0E6B8207A771E5C0EE0DBFD91CE5BAF804FE53F70E61CD2E
|
$PBKDF2-SHA512$iterations=210000$D12C02D1DD15949D867BCA9971BE9987$67E75CDCD14E7F6FDDF96BAACBE9E84E5197FB9FE454FB039F5CD773D7DF558B57DC81DB42B6F7CF0E6B8207A771E5C0EE0DBFD91CE5BAF804FE53F70E61CD2E
|
||||||
|
@ -172,14 +172,28 @@ with lib; {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = "F007D354";
|
default = "F007D354";
|
||||||
};
|
};
|
||||||
};
|
InvalidLoginAttemptCount = mkOption {
|
||||||
|
type = types.int;
|
||||||
|
default = 0;
|
||||||
|
};
|
||||||
|
MustUpdatePassword = mkOption {
|
||||||
|
type = types.int;
|
||||||
|
default = 0;
|
||||||
|
};
|
||||||
|
RowVersion = mkOption {
|
||||||
|
type = types.int;
|
||||||
|
default = 0;
|
||||||
|
};
|
||||||
|
|
||||||
# Omitted database columns:
|
LastActivityDate = mkOption {
|
||||||
# InvalidLoginAttemptCount
|
type = with types; nullOr str;
|
||||||
# LastActivityDate
|
default = null;
|
||||||
# LastLoginDate
|
};
|
||||||
# MustUpdatePassword
|
LastLoginDate = mkOption {
|
||||||
# RowVersion
|
type = with types; nullOr str;
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
};
|
||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{pkgs ? import <nixpkgs> {}, ...}: let
|
{pkgs ? import <nixpkgs> {}, ...}: let
|
||||||
name = "minimal";
|
name = "createusers";
|
||||||
in {
|
in {
|
||||||
inherit name;
|
inherit name;
|
||||||
test = pkgs.nixosTest {
|
test = pkgs.nixosTest {
|
||||||
|
@ -40,9 +40,13 @@ in {
|
||||||
''
|
''
|
||||||
machine.start()
|
machine.start()
|
||||||
machine.wait_for_unit("multi-user.target");
|
machine.wait_for_unit("multi-user.target");
|
||||||
|
output = machine.succeed("cat /var/log/log.txt")
|
||||||
|
print("Log: " + output)
|
||||||
|
print(machine.succeed("cat /var/lib/jellyfin/data/jellyfin.db"))
|
||||||
machine.succeed("file /var/lib/jellyfin/data/jellyfin.db")
|
machine.succeed("file /var/lib/jellyfin/data/jellyfin.db")
|
||||||
users = machine.succeed("sqlite3 /var/lib/jellyfin/data/jellyfin.db -- \"SELECT * FROM Users\"")
|
users = machine.succeed("sqlite3 /var/lib/jellyfin/data/jellyfin.db -- \"SELECT * FROM Users\"")
|
||||||
print(users)
|
print("Users: " + users)
|
||||||
|
|
||||||
if machine.succeed("sqlite3 /var/lib/jellyfin/data/jellyfin.db -- \"SELECT * FROM Users WHERE Username = 'admin'\"") == "":
|
if machine.succeed("sqlite3 /var/lib/jellyfin/data/jellyfin.db -- \"SELECT * FROM Users WHERE Username = 'admin'\"") == "":
|
||||||
assert False, "User not in db"
|
assert False, "User not in db"
|
||||||
'';
|
'';
|
||||||
|
|
|
@ -33,7 +33,6 @@ in {
|
||||||
machine.systemctl("stop jellyfin.service")
|
machine.systemctl("stop jellyfin.service")
|
||||||
machine.wait_until_fails("pgrep jellyfin")
|
machine.wait_until_fails("pgrep jellyfin")
|
||||||
machine.copy_from_vm("/var/lib/jellyfin/data/jellyfin.db", "jellyfin.db")
|
machine.copy_from_vm("/var/lib/jellyfin/data/jellyfin.db", "jellyfin.db")
|
||||||
assert False
|
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue